Use cookie instead of window.name as a tab-configuration hack.

This commit is contained in:
hackademix 2018-10-13 10:08:37 +02:00
parent e44fce3ebd
commit 808fd652be
4 changed files with 30 additions and 36 deletions

View File

@ -1,6 +1,6 @@
"use strict";
{
let marker = JSON.stringify(uuid());
let marker = uuid();
let allUrls = ["<all_urls>"];
let Scripts = {
@ -47,7 +47,7 @@
if (typeof perms !== "string") {
perms = JSON.stringify(perms);
}
return `ns.setup(${perms}, ${marker});`
return `ns.setup(${perms}, "${marker}");`
}
};
@ -104,18 +104,17 @@
: [];
var ChildPolicies = {
async storeTabInfo(tabId, info) {
try {
let preamble = info ? `${marker} + ${JSON.stringify(JSON.stringify([info]))} + ${marker} + "," + ` : "";
await browser.tabs.executeScript(tabId, {
code: `window.name = ${preamble}window.name.split(${marker} + ",").pop();`,
allFrames: true,
matchAboutBlank: true,
runAt: "document_start",
});
} catch (e) {
error(e);
addTabInfoCookie(request, info) {
let h = {
name: "Set-Cookie",
value: `${marker}=${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;
@ -123,7 +122,7 @@
await Scripts.init();
if (!policy.enforced) {
await Scripts.register(`ns.setup(null, ${marker});`, allUrls);
await Scripts.register(Scripts.buildPerms("null"), allUrls);
return;
}

View File

@ -292,6 +292,7 @@ var RequestGuard = (() => {
async onHeadersReceived(request) {
// called for main_frame, sub_frame and object
// check for duplicate calls
let headersModified = false;
let pending = pendingRequests.get(request.requestId);
if (pending) {
if (pending.headersProcessed) {
@ -319,7 +320,10 @@ var RequestGuard = (() => {
capabilities = perms.capabilities;
} else {
if (isMainFrame || type === "sub_frame") {
await Settings.enforceTabRestrictions(tabId);
let unrestricted = ns.unrestrictedTabs.has(tabId) && {unrestricted: true};
if (unrestricted) {
headersModified = ChildPolicies.addTabInfoCookie(request, unrestricted);
}
}
}
if (isMainFrame && !TabStatus.map.has(tabId)) {
@ -331,6 +335,9 @@ var RequestGuard = (() => {
if (header) {
pending.cspHeader = header;
debug(`CSP blocker on %s:`, url, header.value);
headersModified = true;
}
if (headersModified) {
return {responseHeaders};
}
} catch (e) {

View File

@ -90,7 +90,6 @@ var Settings = {
if (typeof unrestrictedTab === "boolean") {
ns.unrestrictedTabs[unrestrictedTab ? "add" : "delete"](tabId);
this.enforceTabRestrictions(tabId, unrestrictedTab);
}
if (reloadAffected) {
browser.tabs.reload(tabId);

View File

@ -47,33 +47,22 @@
this.config.permissions = permissions;
// ugly hack: since now we use registerContentScript instead of the
// filterRequest dynamic script injection hack, we use window.name
// to store per-tab information. We don't want web content to
// mess with it, though, so we wrap it around auto-hiding accessors
// filterRequest dynamic script injection hack, we use a session cookie
// to store per-tab information, erasing it as soon as we see it
// (before any content can access it)
if (this.config.MARKER = MARKER) {
let splitter = `${MARKER},`;
this.getWindowName = () => window.name.split(splitter).pop();
let tabInfoRx = new RegExp(`^${MARKER}\\[([^]*?)\\]${MARKER},`);
let tabInfoMatch = window.name.match(tabInfoRx);
if (tabInfoMatch) {
let cookieRx = new RegExp(`(?:^|;\\s*)${MARKER}=([^;]*)`);
let match = document.cookie.match(cookieRx);
if (match) {
// delete cookie NOW
document.cookie = `${MARKER}=;expires=${new Date(Date.now() - 31536000000).toGMTString()}`;
try {
this.config.tabInfo = JSON.parse(tabInfoMatch[1]);
this.config.tabInfo = JSON.parse(decodeURIComponent(match[1]));
} catch (e) {
error(e);
}
}
Reflect.defineProperty(window.wrappedJSObject, "name", {
get: exportFunction(() => this.getWindowName(), window.wrappedJSObject),
set: exportFunction(value => {
let tabInfoMatch = window.name.match(tabInfoRx);
window.name = tabInfoMatch ? `${tabInfoMatch[0]}${value}` : value;
return value;
}, window.wrappedJSObject)
});
}
if (!this.config.permissions || this.config.tabInfo.unrestricted) {
debug("%s is loading unrestricted by user's choice (%o).", document.URL, this.config);