diff options
-rw-r--r-- | src/bg/ChildPolicies.js | 27 | ||||
-rw-r--r-- | src/bg/RequestGuard.js | 9 | ||||
-rw-r--r-- | src/bg/Settings.js | 1 | ||||
-rw-r--r-- | src/content/staticNS.js | 29 |
4 files changed, 30 insertions, 36 deletions
diff --git a/src/bg/ChildPolicies.js b/src/bg/ChildPolicies.js index f3845bd..b6904f8 100644 --- a/src/bg/ChildPolicies.js +++ b/src/bg/ChildPolicies.js @@ -1,6 +1,6 @@ "use strict"; { - let marker = JSON.stringify(uuid()); + let marker = uuid(); let allUrls = ["<all_urls>"]; let Scripts = { @@ -47,7 +47,7 @@ if (typeof perms !== "string") { perms = JSON.stringify(perms); } - return `ns.setup(${perms}, ${marker});` + return `ns.setup(${perms}, "${marker}");` } }; @@ -104,18 +104,17 @@ : []; var ChildPolicies = { - async storeTabInfo(tabId, info) { - try { - let preamble = info ? `${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + ` : ""; - await browser.tabs.executeScript(tabId, { - code: `window.name = ${preamble}window.name.split(${marker} + ",").pop();`, - allFrames: true, - matchAboutBlank: true, - runAt: "document_start", - }); - } catch (e) { - error(e); + addTabInfoCookie(request, info) { + let h = { + name: "Set-Cookie", + value: `${marker}=${JSON.stringify(info)}` + }; + let {responseHeaders} = request; + if (responseHeaders.some(({value, name}) => h.value === value && h.name === name)) { + return false; } + responseHeaders.push(h); + return true; }, async update(policy, tracing) { if (tracing !== "undefined") Scripts.debug = tracing; @@ -123,7 +122,7 @@ await Scripts.init(); if (!policy.enforced) { - await Scripts.register(`ns.setup(null, ${marker});`, allUrls); + await Scripts.register(Scripts.buildPerms("null"), allUrls); return; } diff --git a/src/bg/RequestGuard.js b/src/bg/RequestGuard.js index 436d043..9be532f 100644 --- a/src/bg/RequestGuard.js +++ b/src/bg/RequestGuard.js @@ -292,6 +292,7 @@ var RequestGuard = (() => { async onHeadersReceived(request) { // called for main_frame, sub_frame and object // check for duplicate calls + let headersModified = false; let pending = pendingRequests.get(request.requestId); if (pending) { if (pending.headersProcessed) { @@ -319,7 +320,10 @@ var RequestGuard = (() => { capabilities = perms.capabilities; } else { if (isMainFrame || type === "sub_frame") { - await Settings.enforceTabRestrictions(tabId); + let unrestricted = ns.unrestrictedTabs.has(tabId) && {unrestricted: true}; + if (unrestricted) { + headersModified = ChildPolicies.addTabInfoCookie(request, unrestricted); + } } } if (isMainFrame && !TabStatus.map.has(tabId)) { @@ -331,6 +335,9 @@ var RequestGuard = (() => { if (header) { pending.cspHeader = header; debug(`CSP blocker on %s:`, url, header.value); + headersModified = true; + } + if (headersModified) { return {responseHeaders}; } } catch (e) { diff --git a/src/bg/Settings.js b/src/bg/Settings.js index a5fca55..0a911ee 100644 --- a/src/bg/Settings.js +++ b/src/bg/Settings.js @@ -90,7 +90,6 @@ var Settings = { if (typeof unrestrictedTab === "boolean") { ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId); - this.enforceTabRestrictions(tabId, unrestrictedTab); } if (reloadAffected) { browser.tabs.reload(tabId); diff --git a/src/content/staticNS.js b/src/content/staticNS.js index 429814c..c746180 100644 --- a/src/content/staticNS.js +++ b/src/content/staticNS.js @@ -47,33 +47,22 @@ this.config.permissions = permissions; // ugly hack: since now we use registerContentScript instead of the - // filterRequest dynamic script injection hack, we use window.name - // to store per-tab information. We don't want web content to - // mess with it, though, so we wrap it around auto-hiding accessors + // filterRequest dynamic script injection hack, we use a session cookie + // to store per-tab information, erasing it as soon as we see it + // (before any content can access it) if (this.config.MARKER = MARKER) { - let splitter = `${MARKER},`; - this.getWindowName = () => window.name.split(splitter).pop(); - - let tabInfoRx = new RegExp(`^${MARKER}\\[([^]*?)\\]${MARKER},`); - - let tabInfoMatch = window.name.match(tabInfoRx); - if (tabInfoMatch) { + let cookieRx = new RegExp(`(?:^|;\\s*)${MARKER}=([^;]*)`); + let match = document.cookie.match(cookieRx); + if (match) { + // delete cookie NOW + document.cookie = `${MARKER}=;expires=${new Date(Date.now() - 31536000000).toGMTString()}`; try { - this.config.tabInfo = JSON.parse(tabInfoMatch[1]); + this.config.tabInfo = JSON.parse(decodeURIComponent(match[1])); } catch (e) { error(e); } } - - Reflect.defineProperty(window.wrappedJSObject, "name", { - get: exportFunction(() => this.getWindowName(), window.wrappedJSObject), - set: exportFunction(value => { - let tabInfoMatch = window.name.match(tabInfoRx); - window.name = tabInfoMatch ? `${tabInfoMatch[0]}${value}` : value; - return value; - }, window.wrappedJSObject) - }); } if (!this.config.permissions || this.config.tabInfo.unrestricted) { debug("%s is loading unrestricted by user's choice (%o).", document.URL, this.config); |