summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhackademix2019-09-29 00:50:43 +0200
committerhackademix2019-09-29 17:29:38 +0200
commitfcd7c4aef0c4b81dafd90ce38f41918ac58da139 (patch)
tree201c9e99b79e6060df9a477beb91e57d19136b6d
parentc3dcf300a60f581cb97ce29a4ba76190cb362604 (diff)
downloadnoscript-fcd7c4aef0c4b81dafd90ce38f41918ac58da139.tar.gz
noscript-fcd7c4aef0c4b81dafd90ce38f41918ac58da139.tar.xz
noscript-fcd7c4aef0c4b81dafd90ce38f41918ac58da139.zip
Replace cookie-based hacks with synchronous messaging (currently shimmed) to retrieve fallback and per-tab restriction policies.
-rw-r--r--src/bg/RequestGuard.js6
-rw-r--r--src/bg/main.js22
-rw-r--r--src/content/content.js9
-rw-r--r--src/content/staticNS.js82
4 files changed, 36 insertions, 83 deletions
diff --git a/src/bg/RequestGuard.js b/src/bg/RequestGuard.js
index 8d30fe7..3936df9 100644
--- a/src/bg/RequestGuard.js
+++ b/src/bg/RequestGuard.js
@@ -287,8 +287,12 @@ var RequestGuard = (() => {
if (policyType) {
let {url, originUrl, documentUrl} = request;
let isFetch = "fetch" === policyType;
+
if ((isFetch || "frame" === policyType) &&
- (((isFetch && !originUrl || url === originUrl) && originUrl === documentUrl
+ (((isFetch && (!originUrl ||
+ browser.runtime.onSyncMessage &&
+ url.includes(browser.runtime.onSyncMessage.ENDPOINT_PREFIX)
+ ) || url === originUrl) && originUrl === documentUrl
// some extensions make them both undefined,
// see https://github.com/eight04/image-picka/issues/150
) ||
diff --git a/src/bg/main.js b/src/bg/main.js
index ed53603..9c30d4f 100644
--- a/src/bg/main.js
+++ b/src/bg/main.js
@@ -141,24 +141,26 @@
},
fetchChildPolicy({url, contextUrl}, sender) {
- if (!url) url = sender.url;
let {tab} = sender;
- let tabUrl = tab.url;
- if (!contextUrl) contextUrl = tabUrl;
-
+ let topUrl = tab.url || TabCache.get(tab.id);
let policy = !Sites.isInternal(url) && ns.isEnforced(tab.id)
? ns.policy : null;
- let permissions = Permissions.ALL;
+ let permissions, unrestricted, cascaded;
if (policy) {
let perms = policy.get(url, contextUrl).perms;
- if (tabUrl && ns.sync.cascadeRestrictions) {
- perms = policy.cascadeRestrictions(perms, tabUrl);
+ cascaded = ns.sync.cascadeRestrictions;
+ if (topUrl && cascaded) {
+ perms = policy.cascadeRestrictions(perms, topUrl);
}
permissions = perms.dry();
- } // otherwise either internal URL or unrestricted
-
- return {permissions};
+ } else {
+ // otherwise either internal URL or unrestricted
+ permissions = new Permissions(Permissions.ALL);
+ unrestricted = true;
+ cascaded = false;
+ }
+ return {permissions, unrestricted, cascaded};
},
async openStandalonePopup() {
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);