From fcd7c4aef0c4b81dafd90ce38f41918ac58da139 Mon Sep 17 00:00:00 2001 From: hackademix Date: Sun, 29 Sep 2019 00:50:43 +0200 Subject: Replace cookie-based hacks with synchronous messaging (currently shimmed) to retrieve fallback and per-tab restriction policies. --- src/content/content.js | 9 ++---- src/content/staticNS.js | 82 ++++++++++--------------------------------------- 2 files changed, 19 insertions(+), 72 deletions(-) (limited to 'src/content') diff --git a/src/content/content.js b/src/content/content.js index e7fb331..eabf7c3 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -58,10 +58,6 @@ var notifyPage = async () => { debug("Page %s shown, %s", document.URL, document.readyState); if (document.readyState === "complete") { try { - if (!("canScript" in ns)) { - ns.fetchPolicy(); - return; - } await Messages.send("pageshow", {seen: seen.list, canScript: ns.canScript}); return true; } catch (e) { @@ -74,8 +70,6 @@ var notifyPage = async () => { return false; } -notifyPage(); - window.addEventListener("pageshow", notifyPage); ns.on("capabilities", () => { @@ -105,3 +99,6 @@ ns.on("capabilities", () => { notifyPage(); }); + +ns.fetchPolicy(); +notifyPage(); diff --git a/src/content/staticNS.js b/src/content/staticNS.js index 7959341..bf91972 100644 --- a/src/content/staticNS.js +++ b/src/content/staticNS.js @@ -33,78 +33,27 @@ backlog.add(eventName); }, - async fetchPolicy() { - let policy = await Messages.send("fetchChildPolicy", {url: document.URL}); - if (!policy) { - debug(`No answer to fetchChildPolicy message. This should not be happening.`); - return false; - } - this.setup(policy.permissions, policy.MARKER, true); - return true; + fetchPolicy() { + let url = document.URL; + let policy = browser.runtime.sendSyncMessage( + {id: "fetchPolicy", url, contextUrl: document.URL}); + if (!policy) { + debug(`No answer to fetchPolicy message. This should not be happening.`); + return false; + } + this.setup(policy); + return true; }, - setup(permissions, MARKER, fetched = false) { - this.config.permissions = permissions; - - // ugly hack: since now we use registerContentScript instead of the - // 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) + setup(policy) { + this.policy = policy; - let checkUnrestricted = challenge => sha256(`${MARKER}:${challenge}`); - - if ((this.config.MARKER = MARKER) && permissions) { - let cookieRx = new RegExp(`(?:^|;\\s*)(${MARKER}(?:_\\d+){2})=([^;]*)`); - let match = document.cookie.match(cookieRx); - if (match) { - let [cookie, cookieName, cookieValue] = match; - // delete cookie NOW - document.cookie = `${cookieName}=;expires=${new Date(Date.now() - 31536000000).toGMTString()}`; - try { - this.config.tabInfo = JSON.parse(decodeURIComponent(cookieValue)); - } catch (e) { - error(e); - } - } else if (UA.isMozilla && window !== window.top) { - // The cookie hack won't work for non-HTTP subframes (issue #48), - // or the cookie might have been deleted in a race condition, - // so here we try to check the parent - let checkParent = null; - try { - checkParent = parent.wrappedJSObject.checkNoScriptUnrestricted; - } catch (e) { - // may throw a SecurityException for cross-origin wrappedJSObject access - } - if (typeof checkParent === "function") { - try { - let challenge = uuid(); - let unrestricted = checkParent(challenge) === checkUnrestricted(challenge); - this.config.tabInfo = {unrestricted, inherited: true}; - } catch (e) { - debug("Exception thrown while checking parent unrestricted tab marker. Something fishy going on...") - error(e); - } - } - } - } - - if (!this.config.permissions || this.config.tabInfo.unrestricted) { - exportFunction(checkUnrestricted, window, {defineAs: "checkNoScriptUnrestricted"}); - debug("%s is loading unrestricted by user's choice (%o).", document.URL, this.config); + if (!policy.permissions || policy.unrestricted) { this.allows = () => true; this.capabilities = Object.assign( new Set(["script"]), { has() { return true; } }); } else { - if (!fetched) { - let hostname = window.location.hostname; - if (hostname && hostname.startsWith("[")) { - // WebExt match patterns don't seem to support IPV6 (Firefox 63)... - debug("Ignoring child policy setup parameters for IPV6 address %s, forcing IPC...", hostname); - this.fetchPolicy(); - return; - } - } - let perms = this.config.permissions; + let perms = policy.permissions; this.capabilities = new Set(perms.capabilities); new DocumentCSP(document).apply(this.capabilities, this.embeddingDocument); } @@ -112,7 +61,8 @@ this.canScript = this.allows("script"); this.fire("capabilities"); }, - config: { permissions: null, tabInfo: {}, MARKER: "" }, + + policy: null, allows(cap) { return this.capabilities && this.capabilities.has(cap); -- cgit v1.2.3