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];
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;
if (!capabilities.has(policyType)) {
let temp = sender.tab.incognito; // we don't want to store in PBM
perms = new Permissions(new Set(capabilities), temp);
perms.capabilities.add(policyType);
/* TODO: handle contextual permissions
if (documentUrl) {
let context = new URL(documentUrl).origin;
let contextualSites = new Sites([context, perms]);
if (contextUrl) {
let context = Sites.optimalKey(contextUrl);
let contextualSites = new Sites([[context, perms]]);
perms = new Permissions(new Set(capabilities), false, contextualSites);
}
*/

View File

@ -228,9 +228,15 @@
isEnforced(tabId = -1) {
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) {
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) {

View File

@ -92,7 +92,7 @@
this.syncFetchPolicy();
} else {
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 => {
browser.runtime.sendSyncMessage(
{id: "fetchPolicy", url, contextUrl: url},
{id: "fetchPolicy", url},
callback);
};
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("192.168", p1.TRUSTED);
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);
let p2 = new Policy(p1.dry());
debug("p1", JSON.stringify(p1.dry()));
@ -55,6 +57,9 @@
() => p1.can("http://192.168.1.2"),
() => p1.can("http://some.onion"),
() => !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);
Sites.onionSecure = onionSecureCurrent;
Test.report();

View File

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

View File

@ -74,12 +74,11 @@ var XSS = (() => {
async function requestListener(request) {
if (ns.isEnforced(request.tabId)) {
let {policy} = ns;
{
let {type} = request;
if (type !== "main_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
}
}