patchright-core 1.55.2 → 1.55.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/reinstall_chrome_beta_mac.sh +1 -1
- package/bin/reinstall_chrome_stable_mac.sh +1 -1
- package/bin/reinstall_msedge_beta_mac.sh +1 -1
- package/bin/reinstall_msedge_dev_mac.sh +1 -1
- package/bin/reinstall_msedge_stable_mac.sh +1 -1
- package/browsers.json +4 -4
- package/lib/client/locator.js +5 -5
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/server/chromium/chromiumSwitches.js +0 -1
- package/lib/server/chromium/crNetworkManager.js +146 -39
- package/lib/server/deviceDescriptorsSource.json +54 -54
- package/lib/vite/htmlReport/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-Di48jgWx.js → codeMirrorModule-DsmF_DpA.js} +1 -1
- package/lib/vite/traceViewer/assets/{defaultSettingsView-szBn8781.js → defaultSettingsView-Cd59AFK5.js} +3 -3
- package/lib/vite/traceViewer/{index.DQvXoPLL.js → index.BivEwfRr.js} +1 -1
- package/lib/vite/traceViewer/index.html +2 -2
- package/lib/vite/traceViewer/{uiMode.dBV3oN9h.js → uiMode.BDvz7Y9W.js} +1 -1
- package/lib/vite/traceViewer/uiMode.html +2 -2
- package/package.json +1 -1
|
@@ -73,7 +73,6 @@ const chromiumSwitches = (assistantMode, channel) => [
|
|
|
73
73
|
"--disable-search-engine-choice-screen",
|
|
74
74
|
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
|
|
75
75
|
"--edge-skip-compat-layer-relaunch",
|
|
76
|
-
assistantMode ? "" : "--enable-automation",
|
|
77
76
|
"--disable-blink-features=AutomationControlled"
|
|
78
77
|
].filter(Boolean);
|
|
79
78
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -533,57 +533,91 @@ class RouteImpl {
|
|
|
533
533
|
if (!allInjections.includes(binding)) allInjections.push(binding);
|
|
534
534
|
}
|
|
535
535
|
if (isTextHtml && allInjections.length) {
|
|
536
|
-
let
|
|
537
|
-
let
|
|
536
|
+
let useNonce = false;
|
|
537
|
+
let scriptNonce = null;
|
|
538
|
+
if (response.isBase64) {
|
|
539
|
+
response.isBase64 = false;
|
|
540
|
+
response.body = Buffer.from(response.body, "base64").toString("utf-8");
|
|
541
|
+
}
|
|
542
|
+
const cspHeaderNames = ["content-security-policy", "content-security-policy-report-only"];
|
|
538
543
|
for (let i = 0; i < response.headers.length; i++) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
useNonce = false;
|
|
548
|
-
} else {
|
|
549
|
-
const scriptSrcRegex = /(script-src[^;]*)(;|$)/;
|
|
550
|
-
const newCspValue = cspValue.replace(scriptSrcRegex, `$1 'nonce-${scriptNonce}'$2`);
|
|
551
|
-
response.headers[i].value = newCspValue;
|
|
544
|
+
const headerName = response.headers[i].name.toLowerCase();
|
|
545
|
+
if (cspHeaderNames.includes(headerName)) {
|
|
546
|
+
const originalCsp = response.headers[i].value || "";
|
|
547
|
+
if (!useNonce) {
|
|
548
|
+
const nonceMatch = originalCsp.match(/script-src[^;]*'nonce-([^'"\s;]+)'/i);
|
|
549
|
+
if (nonceMatch && nonceMatch[1]) {
|
|
550
|
+
scriptNonce = nonceMatch[1];
|
|
551
|
+
useNonce = true;
|
|
552
552
|
}
|
|
553
553
|
}
|
|
554
|
-
|
|
554
|
+
const fixedCsp = this._fixCSP(originalCsp, scriptNonce);
|
|
555
|
+
response.headers[i].value = fixedCsp;
|
|
555
556
|
}
|
|
556
557
|
}
|
|
558
|
+
if (typeof response.body === "string" && response.body.length) {
|
|
559
|
+
response.body = response.body.replace(
|
|
560
|
+
/<meta[^>]*http-equiv=(?:"|')?Content-Security-Policy(?:"|')?[^>]*>/gi,
|
|
561
|
+
(match) => {
|
|
562
|
+
const contentMatch = match.match(/content=(?:"|')([^"']*)(?:"|')/i);
|
|
563
|
+
if (contentMatch && contentMatch[1]) {
|
|
564
|
+
let originalCsp = contentMatch[1];
|
|
565
|
+
originalCsp = originalCsp.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/"/g, '"').replace(/ /g, " ").replace(/&#(d+);/g, (match2, dec) => String.fromCharCode(dec)).replace(/&#x([0-9a-fA-F]+);/g, (match2, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
566
|
+
if (!useNonce) {
|
|
567
|
+
const nonceMatch = originalCsp.match(/script-src[^;]*'nonce-([^'"\s;]+)'/i);
|
|
568
|
+
if (nonceMatch && nonceMatch[1]) {
|
|
569
|
+
scriptNonce = nonceMatch[1];
|
|
570
|
+
useNonce = true;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
const fixedCsp = this._fixCSP(originalCsp, scriptNonce);
|
|
574
|
+
const encodedCsp = fixedCsp.replace(/'/g, "'").replace(/"/g, """);
|
|
575
|
+
return match.replace(contentMatch[1], encodedCsp);
|
|
576
|
+
}
|
|
577
|
+
return match;
|
|
578
|
+
}
|
|
579
|
+
);
|
|
580
|
+
}
|
|
557
581
|
let injectionHTML = "";
|
|
558
582
|
allInjections.forEach((script) => {
|
|
559
583
|
let scriptId = import_crypto.default.randomBytes(22).toString("hex");
|
|
560
584
|
let scriptSource = script.source || script;
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
} else {
|
|
564
|
-
injectionHTML += `<script class="${this._page.delegate.initScriptTag}" id="${scriptId}" type="text/javascript">document.getElementById("${scriptId}")?.remove();${scriptSource}</script>`;
|
|
565
|
-
}
|
|
585
|
+
const nonceAttr = useNonce ? `nonce="${scriptNonce}"` : "";
|
|
586
|
+
injectionHTML += `<script class="${this._page.delegate.initScriptTag}" ${nonceAttr} id="${scriptId}" type="text/javascript">document.getElementById("${scriptId}")?.remove();${scriptSource}</script>`;
|
|
566
587
|
});
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
const
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
588
|
+
const lower = response.body.toLowerCase();
|
|
589
|
+
const headStartIndex = lower.indexOf("<head");
|
|
590
|
+
if (headStartIndex !== -1) {
|
|
591
|
+
const headEndTagIndex = lower.indexOf("</head>", headStartIndex);
|
|
592
|
+
if (headEndTagIndex !== -1) {
|
|
593
|
+
const headOpenEnd = response.body.indexOf(">", headStartIndex) + 1;
|
|
594
|
+
const headContent = response.body.slice(headOpenEnd, headEndTagIndex);
|
|
595
|
+
const headContentLower = headContent.toLowerCase();
|
|
596
|
+
const firstScriptIndex = headContentLower.indexOf("<script");
|
|
597
|
+
if (firstScriptIndex !== -1) {
|
|
598
|
+
const insertPosition = headOpenEnd + firstScriptIndex;
|
|
599
|
+
response.body = response.body.slice(0, insertPosition) + injectionHTML + response.body.slice(insertPosition);
|
|
600
|
+
} else {
|
|
601
|
+
response.body = response.body.slice(0, headEndTagIndex) + injectionHTML + response.body.slice(headEndTagIndex);
|
|
578
602
|
}
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
} else if (/<html[^>]*>/i.test(response.body)) {
|
|
584
|
-
response.body = response.body.replace(/<html[^>]*>/i, `$&<head>${injectionHTML}</head>`);
|
|
603
|
+
} else {
|
|
604
|
+
const headStartTagEnd = response.body.indexOf(">", headStartIndex) + 1;
|
|
605
|
+
response.body = response.body.slice(0, headStartTagEnd) + injectionHTML + response.body.slice(headStartTagEnd);
|
|
606
|
+
}
|
|
585
607
|
} else {
|
|
586
|
-
|
|
608
|
+
const doctypeIndex = lower.indexOf("<!doctype");
|
|
609
|
+
if (doctypeIndex === 0) {
|
|
610
|
+
const doctypeEnd = response.body.indexOf(">", doctypeIndex) + 1;
|
|
611
|
+
response.body = response.body.slice(0, doctypeEnd) + injectionHTML + response.body.slice(doctypeEnd);
|
|
612
|
+
} else {
|
|
613
|
+
const htmlIndex = lower.indexOf("<html");
|
|
614
|
+
if (htmlIndex !== -1) {
|
|
615
|
+
const htmlTagEnd = response.body.indexOf(">", htmlIndex) + 1;
|
|
616
|
+
response.body = response.body.slice(0, htmlTagEnd) + `<head>${injectionHTML}</head>` + response.body.slice(htmlTagEnd);
|
|
617
|
+
} else {
|
|
618
|
+
response.body = injectionHTML + response.body;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
587
621
|
}
|
|
588
622
|
}
|
|
589
623
|
this._fulfilled = true;
|
|
@@ -609,6 +643,79 @@ class RouteImpl {
|
|
|
609
643
|
});
|
|
610
644
|
});
|
|
611
645
|
}
|
|
646
|
+
_fixCSP(csp, scriptNonce) {
|
|
647
|
+
if (!csp || typeof csp !== "string") return csp;
|
|
648
|
+
const directives = csp.split(";").map((d) => d.trim()).filter((d) => d && d.length > 0);
|
|
649
|
+
const fixedDirectives = [];
|
|
650
|
+
let hasScriptSrc = false;
|
|
651
|
+
for (let directive of directives) {
|
|
652
|
+
if (!directive.trim()) continue;
|
|
653
|
+
const parts = directive.trim().split(/s+/);
|
|
654
|
+
if (parts.length === 0) continue;
|
|
655
|
+
const directiveName = parts[0].toLowerCase();
|
|
656
|
+
const directiveValues = parts.slice(1);
|
|
657
|
+
switch (directiveName) {
|
|
658
|
+
case "script-src":
|
|
659
|
+
hasScriptSrc = true;
|
|
660
|
+
let values = [...directiveValues];
|
|
661
|
+
if (scriptNonce && !values.some((v) => v.includes(`nonce-${scriptNonce}`))) {
|
|
662
|
+
values.push(`'nonce-${scriptNonce}'`);
|
|
663
|
+
}
|
|
664
|
+
if (!values.includes("'unsafe-eval'")) {
|
|
665
|
+
values.push("'unsafe-eval'");
|
|
666
|
+
}
|
|
667
|
+
fixedDirectives.push(`script-src ${values.join(" ")}`);
|
|
668
|
+
break;
|
|
669
|
+
case "style-src":
|
|
670
|
+
let styleValues = [...directiveValues];
|
|
671
|
+
if (!styleValues.includes("'unsafe-inline'")) {
|
|
672
|
+
styleValues.push("'unsafe-inline'");
|
|
673
|
+
}
|
|
674
|
+
fixedDirectives.push(`style-src ${styleValues.join(" ")}`);
|
|
675
|
+
break;
|
|
676
|
+
case "img-src":
|
|
677
|
+
let imgValues = [...directiveValues];
|
|
678
|
+
if (!imgValues.includes("data:") && !imgValues.includes("*")) {
|
|
679
|
+
imgValues.push("data:");
|
|
680
|
+
}
|
|
681
|
+
fixedDirectives.push(`img-src ${imgValues.join(" ")}`);
|
|
682
|
+
break;
|
|
683
|
+
case "font-src":
|
|
684
|
+
let fontValues = [...directiveValues];
|
|
685
|
+
if (!fontValues.includes("data:") && !fontValues.includes("*")) {
|
|
686
|
+
fontValues.push("data:");
|
|
687
|
+
}
|
|
688
|
+
fixedDirectives.push(`font-src ${fontValues.join(" ")}`);
|
|
689
|
+
break;
|
|
690
|
+
case "connect-src":
|
|
691
|
+
let connectValues = [...directiveValues];
|
|
692
|
+
const hasWs = connectValues.some((v) => v.includes("ws:") || v.includes("wss:") || v === "*");
|
|
693
|
+
if (!hasWs) {
|
|
694
|
+
connectValues.push("ws:", "wss:");
|
|
695
|
+
}
|
|
696
|
+
fixedDirectives.push(`connect-src ${connectValues.join(" ")}`);
|
|
697
|
+
break;
|
|
698
|
+
case "frame-ancestors":
|
|
699
|
+
let frameAncestorValues = [...directiveValues];
|
|
700
|
+
if (frameAncestorValues.includes("'none'")) {
|
|
701
|
+
frameAncestorValues = ["'self'"];
|
|
702
|
+
}
|
|
703
|
+
fixedDirectives.push(`frame-ancestors ${frameAncestorValues.join(" ")}`);
|
|
704
|
+
break;
|
|
705
|
+
default:
|
|
706
|
+
fixedDirectives.push(directive);
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
if (!hasScriptSrc) {
|
|
711
|
+
if (scriptNonce) {
|
|
712
|
+
fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'nonce-${scriptNonce}'`);
|
|
713
|
+
} else {
|
|
714
|
+
fixedDirectives.push(`script-src 'self' 'unsafe-eval'`);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return fixedDirectives.join("; ");
|
|
718
|
+
}
|
|
612
719
|
async _networkRequestIntercepted(event) {
|
|
613
720
|
if (event.resourceType !== "Document") {
|
|
614
721
|
return;
|