More precise tracking of implicit origins in tab URLs.

This commit is contained in:
hackademix 2022-08-29 23:26:32 +02:00
parent d7e78eda19
commit 96ec2c2a6c
1 changed files with 56 additions and 34 deletions

View File

@ -103,13 +103,34 @@ var TabGuard = (() => {
// we suspect tabs which 1) have not been removed/discarded, 2) are restricted by policy, 3) can run JavaScript
let suspiciousTabs = [...ties].map(TabCache.get).filter(
tab => tab && !tab.discarded && ns.isEnforced(tab.tabId) &&
(tab.url === "about:blank" || ns.policy.can(tab.url, "script")) // TODO: replace about:blank with actual document.domain / window.opener by injecting a content script
tab => tab && !tab.discarded && ns.isEnforced(tab.id) &&
(!(tab._isExplicitOrigin = tab._isExplicitOrigin || /^(?:https?|ftps?|file):/.test(tab.url)) || ns.policy.can(tab.url, "script"))
);
let legitDomains = allowedGroups[tabDomain] || new Set([tabDomain]);
return suspiciousTabs.length > 0 && (async () => {
let otherDomains = new Set(suspiciousTabs.map(tab => getDomain(tab.url)).filter(d => d && !legitDomains.has(d)));
let suspiciousDomains = [];
await Promise.all(suspiciousTabs.map(async (tab) => {
if (!tab._isExplicitOrigin) { // e.g. about:blank
// let's try retrieving actual origin
tab._externalUrl = tab.url;
tab._isExplicitOrigin = true;
try {
tab.url = await browser.tabs.executeScript(tab.id, {
runAt: "document_start",
code: "window.origin === 'null' ? window.location.href : window.origin"
});
} catch (e) {
debug(e);
}
debug(`Real origin for ${tab._externalUrl} (tab ${tab.id}) is ${tab.url}.`);
if (!ns.policy.can(tab.url, "script")) return;
}
suspiciousDomains.push(getDomain(tab.url));
}));
let legitDomains = allowedGroups[tabDomain] || new Set([tabDomain]);
let otherDomains = new Set(suspiciousDomains.filter(d => d && !legitDomains.has(d)));
if (otherDomains.size === 0) return; // no cross-site ties, no party
if (!requestHeaders.some(h => AUTH_HEADERS_RX.test(h.name))) return; // no auth, no party
@ -145,6 +166,7 @@ var TabGuard = (() => {
}
let mustFilter = mainFrame || quietDomains && [...otherDomains].some(d => quietDomains.has(d))
return mustFilter ? filterAuth() : null;
})();
},
postCheck(request) {
let {requestId, tabId} = request;