diff --git a/src/bg/RequestGuard.js b/src/bg/RequestGuard.js index 6ef2514c..4e5e8ae4 100644 --- a/src/bg/RequestGuard.js +++ b/src/bg/RequestGuard.js @@ -317,12 +317,18 @@ async blockedObjects(message, sender) { let {url, documentUrl, policyType} = message; let TAG = `<${policyType.toUpperCase()}>`; - let origin = Sites.origin(url); - let {siteKey} = Sites.parse(url); + + const useDirs = policyType === "x-load"; + const normalize = useDirs ? u => u.replace(/[^/]+$/, '') : u => u; + url = normalize(url); + const contextUrl = normalize(sender.tab.url || documentUrl); + + const origin = Sites.origin(url); + const {siteKey} = Sites.parse(url); const options = [ {label: _("allowLocal", siteKey), checked: true} ]; - if (!url.startsWith("blob:")) { + if (!(url.startsWith("blob:") || useDirs)) { if (siteKey === origin) { origin = new URL(url).protocol; } @@ -341,7 +347,7 @@ } let key = [siteKey, origin][ret.option || 0]; if (!key) return; - let contextUrl = sender.tab.url || documentUrl; + let {siteMatch, contextMatch, perms} = ns.policy.get(key, contextUrl); let {capabilities} = perms; if (!capabilities.has(policyType)) { diff --git a/src/bg/main.js b/src/bg/main.js index e2614c32..6d483aee 100644 --- a/src/bg/main.js +++ b/src/bg/main.js @@ -327,6 +327,13 @@ if (!topUrl) topUrl = url; if (!contextUrl) contextUrl = topUrl; + let xLoadable; + if (contextUrl.startsWith("file:")) { + const contextDir = contextUrl.replace(/[^\/]*$/, ''); + const urls = [...policy.sites.keys()].filter(u => /^file:\/\/.*\//.test(u)); + xLoadable = urls.filter(u => + policy.get(u, contextDir)?.perms?.capabilities.has("x-load")); + } if (Sites.isInternal(url) || !ns.isEnforced(tabId)) { policy = null; } @@ -357,7 +364,7 @@ unrestricted = true; cascaded = false; } - return {permissions, unrestricted, cascaded, isTorBrowser}; + return {permissions, unrestricted, cascaded, isTorBrowser, xLoadable}; }, async init() { diff --git a/src/content/content.js b/src/content/content.js index 5b5f87ce..74f15517 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -167,37 +167,6 @@ window.addEventListener("securitypolicyviolation", async e => { if (!location.protocol.startsWith("http")) { - if (location.protocol == "file:") { - // Suppress load / error events triggered by resources outside current directory - // (see tor-browser#43491) - const suppress = e => { - if (!e.isTrusted) return; - const { target } = e; - const url = new URL(e.filename || - target.currentSrc || - target.src || - target.data || - target.href?.animVal || - target.href, - document.baseURI); - if (url.protocol != "file:") { - return; - } - const curDir = location.pathname.replace(/[^\/]+$/, ""); - const filePath = url.pathname; - if (filePath.startsWith(curDir)) { - return; - } - console.warn(`Suppressing on${e.type} event from ${filePath}`, e.target); - e.preventDefault(); - e.stopPropagation(); - e.stopImmediatePropagation(); - } - document.addEventListener("load", suppress, true); - addEventListener("canplaythrough", suppress, true); - addEventListener("error", suppress, true); - } - // Reporting CSP can only be injected in HTTP responses, // let's emulate them using mutation observers const checked = new Set(); diff --git a/src/content/staticNS.js b/src/content/staticNS.js index 6afeda12..96e56b62 100644 --- a/src/content/staticNS.js +++ b/src/content/staticNS.js @@ -176,6 +176,10 @@ const FILE_OR_FTP = /^(?:file|ftp):$/.test(location.protocol); allows(cap) { return this.capabilities && this.capabilities.has(cap); }, + + canXLoad(url) { + return this.policy?.xLoadable?.includes(url.replace(/[^/]+$/, "")); + } }; globalThis.ns = globalThis.ns ? Object.assign(ns, globalThis.ns) : ns; debug("StaticNS", Date.now(), JSON.stringify(globalThis.ns)); // DEV_ONLY diff --git a/src/manifest.json b/src/manifest.json index 493962e4..12eb64e9 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -122,6 +122,7 @@ "content/content.js", "content/dirindex.js", "/nscl/content/DocumentFreezer.js", + "content/eventsHook.js", "content/syncFetchPolicy.js" ] }, @@ -138,6 +139,7 @@ "/nscl/main/Worlds.main.js", "/nscl/main/patchWorkers.main.js", "/nscl/main/WebGLHook.main.js", + "content/eventsHook.main.js", "/nscl/main/prefetchCSSResources.main.js" ] } diff --git a/src/nscl b/src/nscl index 1b3b7299..a704fa29 160000 --- a/src/nscl +++ b/src/nscl @@ -1 +1 @@ -Subproject commit 1b3b72995780dccb789f478a3a863e9406e51599 +Subproject commit a704fa29f48bfd58a028c76748eb44fd59ad7d4d