Remove ChildPolicies and its dependencies.
This commit is contained in:
parent
c9e06983ba
commit
78063f3412
|
@ -1,200 +0,0 @@
|
|||
"use strict";
|
||||
{
|
||||
let marker = uuid();
|
||||
let allUrls = ["<all_urls>"];
|
||||
|
||||
let Scripts = {
|
||||
references: new Set(),
|
||||
opts: {
|
||||
js: [{file: "/content/dynamicNS.js"}, {}],
|
||||
allFrames: true,
|
||||
matchAboutBlank: true,
|
||||
runAt: "document_start"
|
||||
},
|
||||
async init() {
|
||||
this.init = this.forget;
|
||||
},
|
||||
forget() {
|
||||
for (let script of [...this.references]) {
|
||||
script.unregister();
|
||||
this.references.delete(script);
|
||||
}
|
||||
},
|
||||
debug: false,
|
||||
trace(code) {
|
||||
return this.debug
|
||||
? `console.debug("Executing child policy on %s", document.URL, ${JSON.stringify(code)});${code}`
|
||||
: code
|
||||
;
|
||||
},
|
||||
async register(code, matches, excludeMatches) {
|
||||
debug("Registering child policy.", code, matches, excludeMatches);
|
||||
if (!matches.length) return;
|
||||
try {
|
||||
let opts = Object.assign({}, this.opts);
|
||||
opts.js[1].code = this.trace(code);
|
||||
opts.matches = matches;
|
||||
if (excludeMatches && excludeMatches.length) {
|
||||
opts.excludeMatches = excludeMatches;
|
||||
}
|
||||
this.references.add(await browser.contentScripts.register(opts));
|
||||
} catch (e) {
|
||||
error(e);
|
||||
}
|
||||
},
|
||||
|
||||
buildPerms(perms) {
|
||||
if (typeof perms !== "string") {
|
||||
perms = JSON.stringify(perms);
|
||||
}
|
||||
return `ns.setup(${perms}, "${marker}");`
|
||||
}
|
||||
};
|
||||
|
||||
let flatten = arr => arr.reduce((a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []);
|
||||
|
||||
let protocolRx = /^(\w+):/i;
|
||||
let portRx = /:\d+(?=\/|$)/;
|
||||
let validMatchPatternRx = /^(?:\*|(?:http|ws|ftp)s?|file):\/\/(?:\*|(?:\*\.)?[\w\u0100-\uf000][\w\u0100-\uf000.-]*|\[[\w:]+\])?\/(\*|[^*]*)$/;
|
||||
|
||||
let validMatchPattern = mp => validMatchPatternRx.test(mp);
|
||||
|
||||
let siteKey2MatchPattern = site => {
|
||||
let hasProtocol = site.match(protocolRx);
|
||||
let mp = site;
|
||||
if (hasProtocol) {
|
||||
mp = Sites.cleanUrl(mp);
|
||||
if (!mp) return false;
|
||||
} else {
|
||||
mp = Sites.isSecureDomainKey(site) ? "https://" : "*://";
|
||||
let hostname = Sites.toggleSecureDomainKey(site, false).replace(portRx, '');
|
||||
if (hostname && hostname !== ".") {
|
||||
if (tld.isIp(hostname) || hostname.includes("*")) {
|
||||
mp += hostname;
|
||||
} else {
|
||||
if (!tld.preserveFQDNs) hostname = tld.normalize(hostname);
|
||||
mp += hostname.startsWith(".") ? `*${hostname}` : `*.${hostname}`;
|
||||
}
|
||||
} else {
|
||||
mp += "*";
|
||||
}
|
||||
if (!(hostname && hostname.includes("/"))) mp += "/";
|
||||
}
|
||||
|
||||
return validMatchPattern(mp) &&
|
||||
(mp.endsWith("/") ? `${mp}*` : [mp, `${mp}?*`, `${mp}#*`]);
|
||||
};
|
||||
|
||||
let withFQDNs = patterns => {
|
||||
if (tld.preserveFQDNs) return patterns;
|
||||
let rx = /^(?:\w+|\*):\/\/([^/]*[^.*/])/;
|
||||
return patterns.concat(
|
||||
patterns.map(p => p.replace(rx, (m, host) => tld.isIp(host) ? m : m + ".")
|
||||
).filter(validMatchPattern)
|
||||
);
|
||||
};
|
||||
|
||||
let extraProtocols = patterns => patterns.concat(
|
||||
patterns.filter(p => p.startsWith("*://"))
|
||||
.map(p => p.replace("*", "ftp")));
|
||||
|
||||
let siteKeys2MatchPatterns = keys =>
|
||||
keys ? [... new Set(
|
||||
extraProtocols(withFQDNs(flatten(keys.map(siteKey2MatchPattern)).filter(p => !!p))))]
|
||||
: [];
|
||||
|
||||
var ChildPolicies = {
|
||||
addTabInfoCookie(request, info) {
|
||||
let {tabId, frameId} = request;
|
||||
let h = {
|
||||
name: "Set-Cookie",
|
||||
value: `${marker}_${tabId}_${frameId}=${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;
|
||||
let t0 = Date.now();
|
||||
await Scripts.init();
|
||||
|
||||
if (!policy.enforced) {
|
||||
await Scripts.register(Scripts.buildPerms("null"), allUrls);
|
||||
return;
|
||||
}
|
||||
|
||||
let serialized = policy.dry ? policy.dry(true) : policy;
|
||||
let permsMap = new Map();
|
||||
let trusted = JSON.stringify(serialized.TRUSTED);
|
||||
let untrusted = JSON.stringify(serialized.UNTRUSTED);
|
||||
let presets = {
|
||||
trusted,
|
||||
untrusted,
|
||||
temp: trusted
|
||||
};
|
||||
// map presets to site keys
|
||||
for (let [container, perms] of Object.entries(presets)) {
|
||||
let newKeys = serialized.sites[container];
|
||||
if (!(newKeys && newKeys.length)) continue;
|
||||
let keys = permsMap.get(perms);
|
||||
if (keys) {
|
||||
newKeys = keys.concat(newKeys);
|
||||
}
|
||||
permsMap.set(perms, newKeys);
|
||||
}
|
||||
// map custom permissions to site keys
|
||||
for (let [key, perms] of Object.entries(serialized.sites.custom)) {
|
||||
let permsKey = JSON.stringify(perms);
|
||||
let keys = permsMap.get(permsKey);
|
||||
if (keys) {
|
||||
keys.push(key);
|
||||
} else {
|
||||
permsMap.set(permsKey, [key]);
|
||||
}
|
||||
}
|
||||
|
||||
// compute exclusions
|
||||
let permsMapEntries = [...permsMap];
|
||||
let excludeMap = new Map();
|
||||
|
||||
for (let [perms, keys] of permsMapEntries) {
|
||||
excludeMap.set(perms, siteKeys2MatchPatterns(flatten(
|
||||
permsMapEntries.filter(([other]) => other !== perms)
|
||||
.map(([otherPerms, otherKeys]) => otherKeys))
|
||||
.filter(k => k && k.includes("/") && keys.some(by => Sites.isImplied(k, by)))
|
||||
));
|
||||
}
|
||||
|
||||
// register new content scripts
|
||||
let registering = [];
|
||||
let allMatching = [];
|
||||
for (let [perms, keys] of [...permsMap]) {
|
||||
let match = siteKeys2MatchPatterns(keys);
|
||||
allMatching.push(...match);
|
||||
registering.push(Scripts.register(Scripts.buildPerms(perms), match, excludeMap.get(perms)));
|
||||
}
|
||||
registering.push(Scripts.register(Scripts.buildPerms(serialized.DEFAULT), allUrls, allMatching));
|
||||
await Promise.all(registering);
|
||||
if (tracing) {
|
||||
debug("All the child policies registered in %sms", Date.now() - t0);
|
||||
}
|
||||
},
|
||||
|
||||
getForDocument(policy, url, context = null) {
|
||||
return {
|
||||
permissions: policy && policy.get(url, context).perms.dry(),
|
||||
MARKER: marker
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
if (!browser.contentScripts) { // #chromium fallback
|
||||
Scripts.register = ChildPolicies.update = () => {};
|
||||
}
|
||||
|
||||
}
|
|
@ -262,14 +262,11 @@ var RequestGuard = (() => {
|
|||
}
|
||||
|
||||
function intersectCapabilities(perms, frameAncestors) {
|
||||
if (frameAncestors && frameAncestors.length > 0 && ns.sync.cascadeRestrictions) {
|
||||
if (frameAncestors && frameAncestors.length && ns.sync.cascadeRestrictions) {
|
||||
// cascade top document's restrictions to subframes
|
||||
let topUrl = frameAncestors[frameAncestors.length - 1].url;
|
||||
let topPerms = ns.policy.get(topUrl, topUrl).perms;
|
||||
if (topPerms !== perms) {
|
||||
let topCaps = topPerms.capabilities;
|
||||
return new Set([...perms.capabilities].filter(c => topCaps.has(c)));
|
||||
}
|
||||
perms = policy.cascadeRestrictions(perms,
|
||||
frameAncestors[frameAncestors.length - 1].url)
|
||||
.capabilities;
|
||||
}
|
||||
return perms.capabilities;
|
||||
}
|
||||
|
@ -347,20 +344,12 @@ var RequestGuard = (() => {
|
|||
if (isMainFrame) {
|
||||
if (policy.autoAllowTop && perms === policy.DEFAULT) {
|
||||
policy.set(Sites.optimalKey(url), perms = policy.TRUSTED.tempTwin);
|
||||
promises.push(ChildPolicies.update(policy));
|
||||
}
|
||||
capabilities = perms.capabilities;
|
||||
} else {
|
||||
capabilities = intersectCapabilities(perms, request.frameAncestors);
|
||||
}
|
||||
} else {
|
||||
if (isMainFrame || type === "sub_frame") {
|
||||
let unrestricted = ns.unrestrictedTabs.has(tabId) && {unrestricted: true};
|
||||
if (unrestricted) {
|
||||
headersModified = ChildPolicies.addTabInfoCookie(request, unrestricted);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // else unrestricted, either globally or per-tab
|
||||
if (isMainFrame && !TabStatus.map.has(tabId)) {
|
||||
debug("No TabStatus data yet for noscriptFrame", tabId);
|
||||
TabStatus.record(request, "noscriptFrame",
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
let policyData = (await Storage.get("sync", "policy")).policy;
|
||||
if (policyData && policyData.DEFAULT) {
|
||||
ns.policy = new Policy(policyData);
|
||||
await ChildPolicies.update(policyData, ns.local.debug);
|
||||
} else {
|
||||
await include("/legacy/Legacy.js");
|
||||
ns.policy = await Legacy.createOrMigratePolicy();
|
||||
|
@ -141,11 +140,25 @@
|
|||
return await Settings.import(data);
|
||||
},
|
||||
|
||||
async fetchChildPolicy({url, contextUrl}, sender) {
|
||||
let {tab} = sender;
|
||||
fetchChildPolicy({url, contextUrl}, sender) {
|
||||
if (!url) url = sender.url;
|
||||
let policy = !Sites.isInternal(url) && ns.isEnforced(tab.id) ? ns.policy : null;
|
||||
return ChildPolicies.getForDocument(policy, url, contextUrl || tab.url);
|
||||
let {tab} = sender;
|
||||
let tabUrl = tab.url;
|
||||
if (!contextUrl) contextUrl = tabUrl;
|
||||
|
||||
let policy = !Sites.isInternal(url) && ns.isEnforced(tab.id)
|
||||
? ns.policy : null;
|
||||
|
||||
let permissions = Permissions.ALL;
|
||||
if (policy) {
|
||||
let perms = policy.get(url, contextUrl).perms;
|
||||
if (tabUrl && ns.sync.cascadeRestrictions) {
|
||||
perms = policy.cascadeRestrictions(perms, tabUrl);
|
||||
}
|
||||
permissions = perms.dry();
|
||||
} // otherwise either internal URL or unrestricted
|
||||
|
||||
return {permissions};
|
||||
},
|
||||
|
||||
async openStandalonePopup() {
|
||||
|
@ -170,7 +183,13 @@
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
function onSyncMessage(msg, sender) {
|
||||
switch(msg.id) {
|
||||
case "fetchPolicy":
|
||||
return messageHandler.fetchChildPolicy(msg, sender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var ns = {
|
||||
running: false,
|
||||
|
@ -190,6 +209,8 @@
|
|||
if (this.running) return;
|
||||
this.running = true;
|
||||
|
||||
browser.runtime.onSyncMessage.addListener(onSyncMessage);
|
||||
|
||||
deferWebTraffic(init(),
|
||||
async () => {
|
||||
Commands.install();
|
||||
|
@ -208,6 +229,7 @@
|
|||
stop() {
|
||||
if (!this.running) return;
|
||||
this.running = false;
|
||||
browser.runtime.onSyncMessage.removeListener(onSyncMessage);
|
||||
Messages.removeHandler(messageHandler);
|
||||
RequestGuard.stop();
|
||||
log("STOPPED");
|
||||
|
@ -215,7 +237,6 @@
|
|||
|
||||
async savePolicy() {
|
||||
if (this.policy) {
|
||||
await ChildPolicies.update(this.policy, this.local.debug);
|
||||
await Storage.set("sync", {
|
||||
policy: this.policy.dry()
|
||||
});
|
||||
|
|
|
@ -451,6 +451,16 @@ var {Permissions, Policy, Sites} = (() => {
|
|||
return JSON.stringify(this.dry(true));
|
||||
}
|
||||
|
||||
cascadeRestrictions(perms, topUrl) {
|
||||
let topPerms = ns.policy.get(topUrl, topUrl).perms;
|
||||
if (topPerms !== perms) {
|
||||
let topCaps = topPerms.capabilities;
|
||||
perms = new Permissions([...perms.capabilities].filter(c => topCaps.has(c)),
|
||||
perms.temp, perms.contextual);
|
||||
}
|
||||
return perms;
|
||||
}
|
||||
|
||||
equals(other) {
|
||||
this.snapshot === other.snapshot;
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// ensure the order which manifest scripts and dynamically registered scripts
|
||||
// are executed in doesn't matter for initialization, by using a stub.
|
||||
|
||||
if (!this.ns) {
|
||||
let deferredSetup = null;
|
||||
let nsStub = this.ns = {
|
||||
config: {},
|
||||
setup(permissions, MARKER) {
|
||||
deferredSetup = [permissions, MARKER];
|
||||
},
|
||||
merge: ns => {
|
||||
ns.config = Object.assign(ns.config, nsStub.config);
|
||||
this.ns = ns;
|
||||
if (deferredSetup) {
|
||||
ns.setup(...deferredSetup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,7 +57,6 @@
|
|||
"xss/XSS.js",
|
||||
"bg/ReportingCSP.js",
|
||||
"bg/deferWebTraffic.js",
|
||||
"bg/ChildPolicies.js",
|
||||
"bg/Defaults.js",
|
||||
"bg/RequestGuard.js",
|
||||
"bg/Settings.js",
|
||||
|
|
Loading…
Reference in New Issue