Switch contextual checks to top document matching.

This commit is contained in:
hackademix 2022-01-30 00:38:31 +01:00
parent e34405ab2e
commit db3f1b5878
8 changed files with 28 additions and 16 deletions

View File

@ -259,16 +259,17 @@ var RequestGuard = (() => {
} }
let key = [siteKey, origin][ret.option || 0]; let key = [siteKey, origin][ret.option || 0];
if (!key) return; if (!key) return;
let {siteMatch, contextMatch, perms} = ns.policy.get(key, documentUrl); let contextUrl = sender.tab.url || documentUrl;
let {siteMatch, contextMatch, perms} = ns.policy.get(key, contextUrl);
let {capabilities} = perms; let {capabilities} = perms;
if (!capabilities.has(policyType)) { if (!capabilities.has(policyType)) {
let temp = sender.tab.incognito; // we don't want to store in PBM let temp = sender.tab.incognito; // we don't want to store in PBM
perms = new Permissions(new Set(capabilities), temp); perms = new Permissions(new Set(capabilities), temp);
perms.capabilities.add(policyType); perms.capabilities.add(policyType);
/* TODO: handle contextual permissions /* TODO: handle contextual permissions
if (documentUrl) { if (contextUrl) {
let context = new URL(documentUrl).origin; let context = Sites.optimalKey(contextUrl);
let contextualSites = new Sites([context, perms]); let contextualSites = new Sites([[context, perms]]);
perms = new Permissions(new Set(capabilities), false, contextualSites); perms = new Permissions(new Set(capabilities), false, contextualSites);
} }
*/ */

View File

@ -228,9 +228,15 @@
isEnforced(tabId = -1) { isEnforced(tabId = -1) {
return this.policy.enforced && (tabId === -1 || !this.unrestrictedTabs.has(tabId)); return this.policy.enforced && (tabId === -1 || !this.unrestrictedTabs.has(tabId));
}, },
policyContext(contextualData) {
// contextualData (e.g. a request details object) must contain a tab, a tabId or a documentUrl
// (used as a fallback if tab's top URL cannot be retrieved, e.g. in service workers)
let {tab, tabId, documentUrl} = contextualData;
if (!tab) tab = tabId !== -1 && TabCache.get(tabId);
return tab && tab.url || documentUrl;
},
requestCan(request, capability) { requestCan(request, capability) {
return !this.isEnforced(request.tabId) || this.policy.can(request.url, capability, request.documentURL); return !this.isEnforced(request.tabId) || this.policy.can(request.url, capability, this.policyContext(request));
}, },
computeChildPolicy({url, contextUrl}, sender) { computeChildPolicy({url, contextUrl}, sender) {

View File

@ -92,7 +92,7 @@
this.syncFetchPolicy(); this.syncFetchPolicy();
} else { } else {
this.setup( this.setup(
browser.runtime.sendSyncMessage({id: "fetchPolicy", url, contextUrl: url}) browser.runtime.sendSyncMessage({id: "fetchPolicy", url})
); );
} }
}, },

View File

@ -65,7 +65,7 @@
} }
let syncFetch = callback => { let syncFetch = callback => {
browser.runtime.sendSyncMessage( browser.runtime.sendSyncMessage(
{id: "fetchPolicy", url, contextUrl: url}, {id: "fetchPolicy", url},
callback); callback);
}; };
debug("Initial readyState and body", document.readyState, document.body); debug("Initial readyState and body", document.readyState, document.body);

@ -1 +1 @@
Subproject commit e8efe68bbdaa458fab7a16c665262422ea508119 Subproject commit f04ec6afe193f59ce540f5de9e0d184bf7d8a231

View File

@ -30,7 +30,9 @@
p1.set("10", p1.TRUSTED); p1.set("10", p1.TRUSTED);
p1.set("192.168", p1.TRUSTED); p1.set("192.168", p1.TRUSTED);
p1.set("192.168.69", p1.UNTRUSTED); p1.set("192.168.69", p1.UNTRUSTED);
// secureDomainKey should be "downgraded" by UTRUSTED, issue #126 p1.set("facebook.net", new Permissions([], false,
new Sites([[Sites.optimalKey("https://facebook.com"), p1.TRUSTED]])));
// secureDomainKey should be "downgraded" by UNTRUSTED, issue #126
p1.set(Sites.secureDomainKey("evil.com"), p1.UNTRUSTED); p1.set(Sites.secureDomainKey("evil.com"), p1.UNTRUSTED);
let p2 = new Policy(p1.dry()); let p2 = new Policy(p1.dry());
debug("p1", JSON.stringify(p1.dry())); debug("p1", JSON.stringify(p1.dry()));
@ -55,6 +57,9 @@
() => p1.can("http://192.168.1.2"), () => p1.can("http://192.168.1.2"),
() => p1.can("http://some.onion"), () => p1.can("http://some.onion"),
() => !p1.can("http://evil.com"), () => !p1.can("http://evil.com"),
() => !p1.can("https://facebook.net"),
() => p1.can("https://facebook.net", "script", "https://www.facebook.com"),
() => !p1.can("https://facebook.net", "script", "http://facebook.com"),
]) Test.run(t); ]) Test.run(t);
Sites.onionSecure = onionSecureCurrent; Sites.onionSecure = onionSecureCurrent;
Test.report(); Test.report();

View File

@ -19,10 +19,11 @@
*/ */
(async () => { (async () => {
await include("/test/Test.js"); await include("/nscl/test/Test.js");
Test.include([ Test.include([
"Policy", "/nscl/test/Policy_test.js",
"Storage", "/nscl/test/Storage_test.js",
"/nscl/test/TLD_test.js",
"XSS", "XSS",
"embargoed/XSS", "embargoed/XSS",
]); ]);

View File

@ -74,12 +74,11 @@ var XSS = (() => {
async function requestListener(request) { async function requestListener(request) {
if (ns.isEnforced(request.tabId)) { {
let {policy} = ns;
let {type} = request; let {type} = request;
if (type !== "main_frame") { if (type !== "main_frame") {
if (type === "sub_frame") type = "frame"; if (type === "sub_frame") type = "frame";
if (!policy.can(request.url, type, request.originUrl)) { if (!ns.requestCan(request, type)) {
return ALLOW; // it will be blocked by RequestGuard return ALLOW; // it will be blocked by RequestGuard
} }
} }