summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhackademix2018-09-08 23:09:39 +0200
committerhackademix2018-09-08 23:09:39 +0200
commit4f7d8579afa3b6a71173b3deefaf359d63e1e4e9 (patch)
treeb45998ba15b49ebb5bcebfc6009e3df77c059403 /src
parentb60cbbd49e6d452adeb3abf8cc47ca276000a4db (diff)
downloadnoscript-4f7d8579afa3b6a71173b3deefaf359d63e1e4e9.tar.gz
noscript-4f7d8579afa3b6a71173b3deefaf359d63e1e4e9.tar.xz
noscript-4f7d8579afa3b6a71173b3deefaf359d63e1e4e9.zip
More efficient window.name persistence for tab-scoped permissions.
Diffstat (limited to 'src')
-rw-r--r--src/bg/ChildPolicies.js2
-rw-r--r--src/bg/RequestGuard.js4
-rw-r--r--src/bg/Settings.js6
-rw-r--r--src/content/staticNS.js64
4 files changed, 44 insertions, 32 deletions
diff --git a/src/bg/ChildPolicies.js b/src/bg/ChildPolicies.js
index 99402ca..e8608ad 100644
--- a/src/bg/ChildPolicies.js
+++ b/src/bg/ChildPolicies.js
@@ -102,7 +102,7 @@
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: false,
+ allFrames: true,
matchAboutBlank: true,
runAt: "document_start",
});
diff --git a/src/bg/RequestGuard.js b/src/bg/RequestGuard.js
index 299e1a3..8850542 100644
--- a/src/bg/RequestGuard.js
+++ b/src/bg/RequestGuard.js
@@ -317,6 +317,10 @@ var RequestGuard = (() => {
await ChildPolicies.update(policy);
}
capabilities = perms.capabilities;
+ } else {
+ if (!isMainFrame && type === "sub_frame") {
+ await Settings.enforceTabRestrictions(tabId);
+ }
}
if (isMainFrame && !TabStatus.map.has(tabId)) {
debug("No TabStatus data yet for noscriptFrame", tabId);
diff --git a/src/bg/Settings.js b/src/bg/Settings.js
index 56c88f4..a5fca55 100644
--- a/src/bg/Settings.js
+++ b/src/bg/Settings.js
@@ -90,7 +90,7 @@ var Settings = {
if (typeof unrestrictedTab === "boolean") {
ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId);
- ChildPolicies.storeTabInfo(tabId, unrestrictedTab && {unrestricted: true});
+ this.enforceTabRestrictions(tabId, unrestrictedTab);
}
if (reloadAffected) {
browser.tabs.reload(tabId);
@@ -123,4 +123,8 @@ var Settings = {
}, null, 2);
},
+ async enforceTabRestrictions(tabId, unrestricted = ns.unrestrictedTabs.has(tabId)) {
+ await ChildPolicies.storeTabInfo(tabId, unrestricted && {unrestricted: true});
+ return unrestricted;
+ }
}
diff --git a/src/content/staticNS.js b/src/content/staticNS.js
index 817351a..5deb1ab 100644
--- a/src/content/staticNS.js
+++ b/src/content/staticNS.js
@@ -2,7 +2,7 @@
{
let listenersMap = new Map();
let backlog = new Set();
-
+
let ns = {
debug: true, // DEV_ONLY
get embeddingDocument() {
@@ -32,39 +32,46 @@
}
backlog.add(eventName);
},
-
+
setup(DEFAULT, MARKER) {
this.config.DEFAULT = DEFAULT;
if(!this.config.CURRENT) this.config.CURRENT = DEFAULT;
// ugly hack: since now we use registerContentScript instead of the
- // filterRequest dynamic script injection hack, we use top.name
+ // 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
- this.config.MARKER = MARKER;
- let eraseTabInfoRx = new RegExp(`[^]*${MARKER},?`);
- if (eraseTabInfoRx.test(top.name)) {
- let _name = top.name;
+
+ if (this.config.MARKER = MARKER) {
+
let tabInfoRx = new RegExp(`^${MARKER}\\[([^]*?)\\]${MARKER},`);
- if (top === window) { // wrap to hide
- Reflect.defineProperty(top.wrappedJSObject, "name", {
- get: exportFunction(() => top.name.replace(eraseTabInfoRx, ""), top.wrappedJSObject),
- set: exportFunction(value => {
- let preamble = top.name.match(tabInfoRx);
- top.name = `${preamble && preamble[0] || ""}${value}`;
- return value;
- }, top.wrappedJSObject)
- });
+ let name = window.name;
+ try {
+ name = top.name;
+ } catch(e) {
+ // won't work cross-origin
}
- let tabInfoMatch = _name.match(tabInfoRx);
- if (tabInfoMatch) try {
- this.config.tabInfo = JSON.parse(tabInfoMatch[1]);
- } catch (e) {
- error(e);
+ let tabInfoMatch = name.match(tabInfoRx);
+ if (tabInfoMatch) {
+ try {
+ this.config.tabInfo = JSON.parse(tabInfoMatch[1]);
+ } catch (e) {
+ error(e);
+ }
}
+ let splitter = `${MARKER},`;
+ this.getWindowName = () => window.name.split(splitter).pop();
+ 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.DEFAULT || this.config.tabInfo.unrestricted) {
+ debug("%s is loading unrestricted by user's choice (%o).", document.URL, this.config);
this.allows = () => true;
this.capabilities = Object.assign(
new Set(["script"]), { has() { return true; } });
@@ -73,24 +80,21 @@
this.capabilities = new Set(perms.capabilities);
new DocumentCSP(document).apply(this.capabilities, this.embeddingDocument);
}
-
+
this.canScript = this.allows("script");
this.fire("capabilities");
},
config: { DEFAULT: null, CURRENT: null, tabInfo: {}, MARKER: "" },
-
+
allows(cap) {
return this.capabilities && this.capabilities.has(cap);
},
-
+
getWindowName() {
- let marker = this.config.MARKER;
- return (top === window && marker) ?
- window.name.split(`${marker},`).pop()
- : window.name;
+ return window.name;
}
};
-
+
if (this.ns) {
this.ns.merge(ns);
} else {