From 2875397fb887a5b09b5f39d6b3a75419a516dd07 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Thu, 26 Aug 2021 11:50:36 +0200 Subject: improve signing\n\nSignature timestamp is now handled in a saner way. Sha256 implementation is no longer pulled in contexts that don't require it. --- background/main.js | 2 +- background/policy_injector.js | 33 +++++++++++++++++---------------- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'background') diff --git a/background/main.js b/background/main.js index 85f8ce8..2c8a87b 100644 --- a/background/main.js +++ b/background/main.js @@ -69,7 +69,7 @@ function on_headers_received(details) skip = true; } - headers = inject_csp_headers(details, headers, policy); + headers = inject_csp_headers(headers, policy); skip = skip || (details.statusCode >= 300 && details.statusCode < 400); if (!skip) { diff --git a/background/policy_injector.js b/background/policy_injector.js index 1d4db6f..72318d4 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -16,25 +16,27 @@ * IMPORTS_END */ -function inject_csp_headers(details, headers, policy) +function inject_csp_headers(headers, policy) { - const url = details.url; - - let orig_csp_headers; + let csp_headers; let old_signature; let hachette_header; for (const header of headers.filter(h => h.name === "x-hachette")) { - const match = /^([^%])(%.*)$/.exec(header.value); + /* x-hachette header has format: _0_ */ + const match = /^([^_]+)_(0_.*)$/.exec(header.value); if (!match) continue; - const old_data = extract_signed(...match.splice(1, 2), [[0]]); - if (!old_data || old_data.url !== url) + const result = extract_signed(...match.slice(1, 3)); + if (result.fail) continue; + /* This should succeed - it's our self-produced valid JSON. */ + const old_data = JSON.parse(decodeURIComponent(result.data)); + /* Confirmed- it's the originals, smuggled in! */ - orig_csp_headers = old_data.csp_headers; + csp_headers = old_data.csp_headers; old_signature = old_data.policy_sig; hachette_header = header; @@ -46,24 +48,23 @@ function inject_csp_headers(details, headers, policy) headers.push(hachette_header); } - orig_csp_headers = orig_csp_headers || + csp_headers = csp_headers || 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, !policy.allow)); if (old_signature) - headers = headers.filter(h => h.name.search(old_signature) === -1); + headers = headers.filter(h => h.value.search(old_signature) === -1); - const sanitizer = h => sanitize_csp_header(h, policy); - headers.push(...orig_csp_headers.map(sanitizer)); + headers.push(...csp_headers.map(h => sanitize_csp_header(h, policy))); const policy_str = encodeURIComponent(JSON.stringify(policy)); - const policy_sig = sign_data(policy_str, new Date()); + const signed_policy = sign_data(policy_str, new Date().getTime()); const later_30sec = new Date(new Date().getTime() + 30000).toGMTString(); headers.push({ name: "Set-Cookie", - value: `hachette-${policy_sig}=${policy_str}; Expires=${later_30sec};` + value: `hachette-${signed_policy.join("=")}; Expires=${later_30sec};` }); /* @@ -71,9 +72,9 @@ function inject_csp_headers(details, headers, policy) * 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_sig, url}; + let hachette_data = {csp_headers, policy_sig: signed_policy[0]}; hachette_data = encodeURIComponent(JSON.stringify(hachette_data)); - hachette_header.value = sign_data(hachette_data, 0) + hachette_data; + hachette_header.value = sign_data(hachette_data, 0).join("_"); /* To ensure there is a CSP header if required */ if (!policy.allow) -- cgit v1.2.3