From 6b53d6c840140fc5df6d7638808b978d96502a35 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Mon, 23 Aug 2021 11:05:51 +0200 Subject: use StreamFilter under Mozilla to prevent csp tags from blocking our injected scripts --- background/policy_injector.js | 61 +++++++++++-------------------------------- 1 file changed, 15 insertions(+), 46 deletions(-) (limited to 'background/policy_injector.js') diff --git a/background/policy_injector.js b/background/policy_injector.js index 3398b53..1d4db6f 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -8,36 +8,21 @@ /* * IMPORTS_START - * IMPORT get_storage - * IMPORT browser - * IMPORT is_chrome - * IMPORT gen_nonce - * IMPORT is_privileged_url * IMPORT sign_data * IMPORT extract_signed - * IMPORT query_best * IMPORT sanitize_csp_header * IMPORT csp_rule * IMPORT is_csp_header_name * IMPORTS_END */ -var storage; - -function headers_inject(details) +function inject_csp_headers(details, headers, policy) { const url = details.url; - if (is_privileged_url(url)) - return; - - const [pattern, settings] = query_best(storage, url); - const allow = !!(settings && settings.allow); - const nonce = gen_nonce(); let orig_csp_headers; let old_signature; let hachette_header; - let headers = details.responseHeaders; for (const header of headers.filter(h => h.name === "x-hachette")) { const match = /^([^%])(%.*)$/.exec(header.value); @@ -50,7 +35,7 @@ function headers_inject(details) /* Confirmed- it's the originals, smuggled in! */ orig_csp_headers = old_data.csp_headers; - old_signature = old_data.policy_signature; + old_signature = old_data.policy_sig; hachette_header = header; break; @@ -65,21 +50,20 @@ function headers_inject(details) headers.filter(h => is_csp_header_name(h.name)); /* When blocking remove report-only CSP headers that snitch on us. */ - headers = headers.filter(h => !is_csp_header_name(h.name, !allow)); + headers = headers.filter(h => !is_csp_header_name(h.name, !policy.allow)); if (old_signature) headers = headers.filter(h => h.name.search(old_signature) === -1); - const policy_object = {allow, nonce, url}; - const sanitizer = h => sanitize_csp_header(h, policy_object); + const sanitizer = h => sanitize_csp_header(h, policy); headers.push(...orig_csp_headers.map(sanitizer)); - const policy = encodeURIComponent(JSON.stringify(policy_object)); - const policy_signature = sign_data(policy, new Date()); + const policy_str = encodeURIComponent(JSON.stringify(policy)); + const policy_sig = sign_data(policy_str, new Date()); const later_30sec = new Date(new Date().getTime() + 30000).toGMTString(); headers.push({ name: "Set-Cookie", - value: `hachette-${policy_signature}=${policy}; Expires=${later_30sec};` + value: `hachette-${policy_sig}=${policy_str}; Expires=${later_30sec};` }); /* @@ -87,37 +71,22 @@ function headers_inject(details) * These are signed with a time of 0, as it's not clear there is a limit on * how long Firefox might retain headers in the cache. */ - let hachette_data = {csp_headers: orig_csp_headers, policy_signature, url}; + let hachette_data = {csp_headers: orig_csp_headers, policy_sig, url}; hachette_data = encodeURIComponent(JSON.stringify(hachette_data)); hachette_header.value = sign_data(hachette_data, 0) + hachette_data; /* To ensure there is a CSP header if required */ - if (!allow) - headers.push({name: "content-security-policy", value: csp_rule(nonce)}); + if (!policy.allow) + headers.push({ + name: "content-security-policy", + value: csp_rule(policy.nonce) + }); - return {responseHeaders: headers}; -} - -async function start_policy_injector() -{ - storage = await get_storage(); - - let extra_opts = ["blocking", "responseHeaders"]; - if (is_chrome) - extra_opts.push("extraHeaders"); - - browser.webRequest.onHeadersReceived.addListener( - headers_inject, - { - urls: [""], - types: ["main_frame", "sub_frame"] - }, - extra_opts - ); + return headers; } /* * EXPORTS_START - * EXPORT start_policy_injector + * EXPORT inject_csp_headers * EXPORTS_END */ -- cgit v1.2.3