From db837b42c7d2e062edbf674ef19739573f375816 Mon Sep 17 00:00:00 2001 From: velzie Date: Mon, 2 Sep 2024 20:38:06 -0400 Subject: [PATCH] fix some jank --- src/client/dom/postmessage.ts | 17 ++++++++++++++++- src/client/shared/requests/beacon.ts | 8 +++++--- src/client/shared/requests/xmlhttprequest.ts | 3 ++- src/worker/fetch.ts | 12 +++++++++++- src/worker/index.ts | 13 ++++++++++--- 5 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/client/dom/postmessage.ts b/src/client/dom/postmessage.ts index c39edc4..d313edb 100644 --- a/src/client/dom/postmessage.ts +++ b/src/client/dom/postmessage.ts @@ -11,7 +11,22 @@ export default function (client: ScramjetClient) { // if we were given any object that came from the real realm we can use that to get the real origin // and this works in every case EXCEPT for the fact that all three arguments can be strings which are copied instead of cloned // so we have to use `$setrealm` which will pollute this with an object from the real realm - const pollutant = ctx.this[POLLUTANT] || {}; + + let pollutant; + + if (typeof ctx.args[0] === "object" && ctx.args[0] !== null) { + pollutant = ctx.args[0]; // try to use the first object we can find because it's more reliable + } else if (typeof ctx.args[2] === "object" && ctx.args[2] !== null) { + pollutant = ctx.args[2]; // next try to use transfer + } else if ( + POLLUTANT in ctx.this && + typeof ctx.this[POLLUTANT] === "object" && + ctx.this[POLLUTANT] !== null + ) { + pollutant = ctx.this[POLLUTANT]; // lastly try to use the object from $setrealm + } else { + pollutant = {}; // give up + } // and now we can steal Function from the caller's realm const { diff --git a/src/client/shared/requests/beacon.ts b/src/client/shared/requests/beacon.ts index ccba7e3..47bd05e 100644 --- a/src/client/shared/requests/beacon.ts +++ b/src/client/shared/requests/beacon.ts @@ -1,8 +1,10 @@ -export default function (client, self) { - // goodybye spyware~ +import { encodeUrl } from "../../../shared/rewriters/url"; +import { ScramjetClient } from "../../client"; + +export default function (client: ScramjetClient, self) { client.Proxy("navigator.sendBeacon", { apply(ctx) { - ctx.return(true); + ctx.args[0] = encodeUrl(ctx.args[0], client.meta); }, }); } diff --git a/src/client/shared/requests/xmlhttprequest.ts b/src/client/shared/requests/xmlhttprequest.ts index 51de095..77f617b 100644 --- a/src/client/shared/requests/xmlhttprequest.ts +++ b/src/client/shared/requests/xmlhttprequest.ts @@ -1,8 +1,9 @@ import { config, decodeUrl, encodeUrl, rewriteHeaders } from "../../../shared"; import { ScramjetClient } from "../../client"; +const nativeworker = Worker; export default function (client: ScramjetClient, self: Self) { - const worker = new Worker(config.sync); + const worker = new nativeworker(config.sync); const ARGS = Symbol("xhr original args"); const HEADERS = Symbol("xhr headers"); diff --git a/src/worker/fetch.ts b/src/worker/fetch.ts index f7d58a6..0ff3fae 100644 --- a/src/worker/fetch.ts +++ b/src/worker/fetch.ts @@ -218,7 +218,17 @@ async function handleResponse( // scramjet runtime can use features that permissions-policy blocks delete responseHeaders["permissions-policy"]; - if (crossOriginIsolated) { + if ( + crossOriginIsolated && + [ + "document", + "iframe", + "worker", + "sharedworker", + "style", + "script", + ].includes(destination) + ) { responseHeaders["Cross-Origin-Embedder-Policy"] = "require-corp"; responseHeaders["Cross-Origin-Opener-Policy"] = "same-origin"; } diff --git a/src/worker/index.ts b/src/worker/index.ts index 0887803..d1b5e31 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -151,10 +151,17 @@ export class ScramjetServiceWorker { base: new URL(origin), }); + const headers = { + "Content-Type": "application/javascript", + }; + + if (crossOriginIsolated) { + headers["Cross-Origin-Opener-Policy"] = "same-origin"; + headers["Cross-Origin-Embedder-Policy"] = "require-corp"; + } + return new Response(rewritten, { - headers: { - "Content-Type": "application/javascript", - }, + headers, }); }