Stateless-compatibile TabGuard.

This commit is contained in:
hackademix 2024-10-21 18:21:35 +02:00
parent 95da855ff5
commit 6344d120cb
No known key found for this signature in database
GPG Key ID: 231A83AFDA9C2434
4 changed files with 64 additions and 18 deletions

View File

@ -18,23 +18,62 @@
* this program. If not, see <https://www.gnu.org/licenses/>. * this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
// depends on /nscl/common/SessionCache.js
// depends on /nscl/service/TabCache.js
// depends on /nscl/service/TabTies.js
var TabGuard = (() => { var TabGuard = (() => {
(async () => { await include(["/nscl/service/TabCache.js", "/nscl/service/TabTies.js"]); })();
const anonymizedTabs = new Map(); let anonymizedTabs = new Map();
browser.tabs.onRemoved.addListener(tab => { browser.tabs.onRemoved.addListener(({id}) => {
anonymizedTabs.delete(tab.id); if (anonymizedTabs.has(id)) {
anonymizedTabs.delete(id);
session.save();
}
}); });
const anonymizedRequests = new Set(); const anonymizedRequests = new Set(); // ephemeral, lifespan is webRequest
let allowedGroups, filteredGroups; // Domain groups:
let forget = () => { // property keys are domains, property values are domain Sets
allowedGroups = {}; // (session-persisted)
filteredGroups = {};
let Groups = {
allowed: {},
filtered: {},
}; };
forget(); const forget = () => {
Groups.allowed = {};
Groups.filtered = {};
};
const groupsSerDe = (source, callback) => {
const target = {};
for (const [which, group] of Object.entries(source)) {
const targetGroup = {};
for (const [domain, otherDomains] of Object.entries(group)) {
targetGroup[domain] = callback(otherDomains);
}
target[which] = targetGroup;
}
return target;
};
const session = new SessionCache(
"TabGuard", // storageKey
{
afterLoad(data) { // afterLoad
if (!data) return;
anonymizedTabs = new Map(data.anonymizedTabs);
Groups = groupsSerDe(data.Groups, domainsArray => new Set(domainsArray));
},
beforeSave() {
return {
anonymizedTabs: [...anonymizedTabs],
Groups: groupsSerDe(Groups, domainsSet => [...domainsSet]),
}
},
}
);
function mergeGroups(groups, function mergeGroups(groups,
{tabDomain, otherDomains}, /* anonymizedTabInfo */ {tabDomain, otherDomains}, /* anonymizedTabInfo */
@ -48,6 +87,7 @@ var TabGuard = (() => {
(groups[d] || (groups[d] = new Set())).add(tabDomain); (groups[d] || (groups[d] = new Set())).add(tabDomain);
} }
} }
session.save();
} }
const AUTH_HEADERS_RX = /^(?:authorization|cookie)/i; const AUTH_HEADERS_RX = /^(?:authorization|cookie)/i;
@ -65,9 +105,10 @@ var TabGuard = (() => {
return flat; return flat;
} }
let scheduledCuts = new Set(); const scheduledCuts = new Set();
return { return {
wakening: Promise.all([TabCache.wakening, TabTies.wakening, session.load()]),
forget, forget,
// must be called from a webRequest.onBeforeSendHeaders blocking listener // must be called from a webRequest.onBeforeSendHeaders blocking listener
onSend(request) { onSend(request) {
@ -199,7 +240,7 @@ var TabGuard = (() => {
suspiciousDomains.push(getDomain(tab.url)); suspiciousDomains.push(getDomain(tab.url));
})); }));
const legitDomains = allowedGroups[tabDomain] || new Set(); const legitDomains = Groups.allowed[tabDomain] || new Set();
legitDomains.add(tabDomain); legitDomains.add(tabDomain);
let otherDomains = new Set(suspiciousDomains.filter(d => d && !legitDomains.has(d))); let otherDomains = new Set(suspiciousDomains.filter(d => d && !legitDomains.has(d)));
@ -213,11 +254,13 @@ var TabGuard = (() => {
requestHeaders = requestHeaders.filter(h => !AUTH_HEADERS_RX.test(h.name)); requestHeaders = requestHeaders.filter(h => !AUTH_HEADERS_RX.test(h.name));
debug("[TabGuard] Removing auth headers from %o (%o)", request, requestHeaders); debug("[TabGuard] Removing auth headers from %o (%o)", request, requestHeaders);
anonymizedTabs.set(tabId, {tabDomain, otherDomains: [...otherDomains]}); anonymizedTabs.set(tabId, {tabDomain, otherDomains: [...otherDomains]});
session.save();
anonymizedRequests.add(request.id); anonymizedRequests.add(request.id);
return {requestHeaders}; return {requestHeaders};
}; };
let quietDomains = filteredGroups[tabDomain]; let quietDomains = Groups.filtered[tabDomain];
if (mainFrame) { if (mainFrame) {
const promptOption = ns.sync.TabGuardPrompt; const promptOption = ns.sync.TabGuardPrompt;
@ -238,9 +281,9 @@ var TabGuard = (() => {
if (ret.button !== 0) { if (ret.button !== 0) {
return {cancel: true}; return {cancel: true};
} }
const groups = ret.option === 0 ? filteredGroups : allowedGroups; const groups = ret.option === 0 ? Groups.filtered : Groups.allowed;
mergeGroups(groups, {tabDomain, otherDomains}); mergeGroups(groups, {tabDomain, otherDomains});
return groups === filteredGroups ? filterAuth() : null; return groups === Groups.filtered ? filterAuth() : null;
})(); })();
} }
} }
@ -288,7 +331,7 @@ var TabGuard = (() => {
allow(tabId) { allow(tabId) {
if (!TabGuard.isAnonymizedTab(tabId)) return; if (!TabGuard.isAnonymizedTab(tabId)) return;
const info = this.getAnonymizedTabInfo(tabId); const info = this.getAnonymizedTabInfo(tabId);
mergeGroups(allowedGroups, info); mergeGroups(Groups.allowed, info);
} }
} }
})(); })();

View File

@ -87,7 +87,7 @@
if (!isTorBrowser) { if (!isTorBrowser) {
await include("/nscl/service/prefetchCSSResources.js"); await include("/nscl/service/prefetchCSSResources.js");
} }
await TabGuard.wakening;
await RequestGuard.start(); await RequestGuard.start();
try { try {

View File

@ -58,9 +58,12 @@
"/nscl/common/DNS.js", "/nscl/common/DNS.js",
"/nscl/common/AddressMatcherWithDNS.js", "/nscl/common/AddressMatcherWithDNS.js",
"/nscl/common/iputil.js", "/nscl/common/iputil.js",
"/nscl/common/SessionCache.js",
"/nscl/service/DocStartInjection.js", "/nscl/service/DocStartInjection.js",
"/nscl/service/LastListener.js", "/nscl/service/LastListener.js",
"/nscl/service/patchWorkers.js", "/nscl/service/patchWorkers.js",
"/nscl/service/TabCache.js",
"/nscl/service/TabTies.js",
"ui/Prompts.js", "ui/Prompts.js",
"xss/XSS.js", "xss/XSS.js",
"bg/ReportingCSP.js", "bg/ReportingCSP.js",

@ -1 +1 @@
Subproject commit 3ba8d9a4cb4c57abb2611343cc8641882f5715c2 Subproject commit 9705b11ac271b44c70fc086a162326a83c0b2dbe