diff options
author | jahoti <jahoti@tilde.team> | 2021-09-21 00:00:00 +0000 |
---|---|---|
committer | jahoti <jahoti@tilde.team> | 2021-09-21 00:00:00 +0000 |
commit | 59fb32a341d42c685b5167c3d8b4d7b87c49fd18 (patch) | |
tree | 17143cd40a59eb06b4e698d6fd9ca9d02abaf2b9 /background | |
parent | b1444d9c9ea065d7c97d5809c3ec5259cb01a1da (diff) | |
parent | 960363e7dd98a724246320e49c3fbaff9d68d1bd (diff) | |
download | browser-extension-59fb32a341d42c685b5167c3d8b4d7b87c49fd18.tar.gz browser-extension-59fb32a341d42c685b5167c3d8b4d7b87c49fd18.zip |
Merge branch 'master' into jahoti-update
Diffstat (limited to 'background')
-rw-r--r-- | background/cookie_filter.js | 17 | ||||
-rw-r--r-- | background/main.js | 4 | ||||
-rw-r--r-- | background/page_actions_server.js | 18 | ||||
-rw-r--r-- | background/policy_injector.js | 76 | ||||
-rw-r--r-- | background/storage.js | 4 | ||||
-rw-r--r-- | background/storage_server.js | 4 | ||||
-rw-r--r-- | background/stream_filter.js | 11 |
7 files changed, 99 insertions, 35 deletions
diff --git a/background/cookie_filter.js b/background/cookie_filter.js index fea2d23..64d18b2 100644 --- a/background/cookie_filter.js +++ b/background/cookie_filter.js @@ -1,7 +1,8 @@ /** - * part of Hachette - * Filtering request headers to remove hachette cookies that might have slipped - * through. + * This file is part of Haketilo. + * + * Function: Filtering request headers to remove haketilo cookies that might + * have slipped through. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. @@ -13,29 +14,29 @@ * IMPORTS_END */ -function is_valid_hachette_cookie(cookie) +function is_valid_haketilo_cookie(cookie) { - const match = /^hachette-(\w*)=(.*)$/.exec(cookie); + const match = /^haketilo-(\w*)=(.*)$/.exec(cookie); if (!match) return false; return !extract_signed(match.slice(1, 3)).fail; } -function remove_hachette_cookies(header) +function remove_haketilo_cookies(header) { if (header.name !== "Cookie") return header; const cookies = header.value.split("; "); - const value = cookies.filter(c => !is_valid_hachette_cookie(c)).join("; "); + const value = cookies.filter(c => !is_valid_haketilo_cookie(c)).join("; "); return value ? {name: "Cookie", value} : null; } function filter_cookie_headers(headers) { - return headers.map(remove_hachette_cookies).filter(h => h); + return headers.map(remove_haketilo_cookies).filter(h => h); } /* diff --git a/background/main.js b/background/main.js index 03cd5d7..40b3a9e 100644 --- a/background/main.js +++ b/background/main.js @@ -1,5 +1,7 @@ /** - * Hachette main background script + * This file is part of Haketilo. + * + * Function: Main background script. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/background/page_actions_server.js b/background/page_actions_server.js index b0db5f5..156a79f 100644 --- a/background/page_actions_server.js +++ b/background/page_actions_server.js @@ -1,5 +1,7 @@ /** - * Hachette serving of page actions to content scripts + * This file is part of Haketilo. + * + * Function: Serving page actions to content scripts. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. @@ -25,15 +27,19 @@ let policy_observable; function send_actions(url, port) { - let [pattern, settings] = query_best(storage, url); - if (!settings) - settings = {allow: policy_observable && policy_observable.value}; + const [pattern, queried_settings] = query_best(storage, url); + + const settings = {allow: policy_observable && policy_observable.value}; + Object.assign(settings, queried_settings); + if (settings.components) + settings.allow = false; + const repos = storage.get_all(TYPE_PREFIX.REPO); port.postMessage(["settings", [pattern, settings, repos]]); - let components = settings.components; - let processed_bags = new Set(); + const components = settings.components; + const processed_bags = new Set(); if (components !== undefined) send_scripts([components], port, processed_bags); diff --git a/background/policy_injector.js b/background/policy_injector.js index 318190b..881595b 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -1,5 +1,7 @@ /** - * Hachette injecting policy to page using webRequest + * This file is part of Haketilo. + * + * Function: Injecting policy to page by modifying HTTP headers. * * Copyright (C) 2021 Wojtek Kosior * Copyright (C) 2021 jahoti @@ -10,33 +12,81 @@ * IMPORTS_START * IMPORT sign_data * IMPORT extract_signed - * IMPORT sanitize_csp_header * IMPORT make_csp_rule - * IMPORT is_csp_header_name + * IMPORT csp_header_regex * IMPORTS_END */ function inject_csp_headers(headers, policy) { - if (!policy.allow || policy.has_payload) { - /* Remove report-only CSP headers that snitch on us. */ - headers = headers.filter(h => !is_csp_header_name(h.name, true)); + let csp_headers; + let old_signature; + let haketilo_header; - /* Add our own CSP header */ - headers.push({ - name: "content-security-policy", - value: make_csp_rule(policy) - }); + for (const header of headers.filter(h => h.name === "x-haketilo")) { + /* x-haketilo header has format: <signature>_0_<data> */ + const match = /^([^_]+)_(0_.*)$/.exec(header.value); + if (!match) + continue; + + 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! */ + csp_headers = old_data.csp_headers; + old_signature = old_data.policy_sig; + + haketilo_header = header; + break; + } + + if (policy.has_payload) { + csp_headers = []; + const non_csp_headers = []; + const header_list = + h => csp_header_regex.test(h) ? csp_headers : non_csp_headers; + headers.forEach(h => header_list(h.name).push(h)); + headers = non_csp_headers; + } else { + headers.push(...csp_headers || []); } - + + if (!haketilo_header) { + haketilo_header = {name: "x-haketilo"}; + headers.push(haketilo_header); + } + + if (old_signature) + headers = headers.filter(h => h.value.search(old_signature) === -1); + const policy_str = encodeURIComponent(JSON.stringify(policy)); 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-${signed_policy.join("=")}; Expires=${later_30sec};` + value: `haketilo-${signed_policy.join("=")}; Expires=${later_30sec};` }); + /* + * Smuggle in the signature and the original CSP headers for future use. + * 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 haketilo_data = {csp_headers, policy_sig: signed_policy[0]}; + haketilo_data = encodeURIComponent(JSON.stringify(haketilo_data)); + haketilo_header.value = sign_data(haketilo_data, 0).join("_"); + + if (!policy.allow) { + headers.push({ + name: "content-security-policy", + value: make_csp_rule(policy) + }); + } + return headers; } diff --git a/background/storage.js b/background/storage.js index 12c0c61..a4e626a 100644 --- a/background/storage.js +++ b/background/storage.js @@ -1,5 +1,7 @@ /** - * Hachette storage manager + * This file is part of Haketilo. + * + * Function: Storage manager. * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/background/storage_server.js b/background/storage_server.js index 2252eb5..73126d4 100644 --- a/background/storage_server.js +++ b/background/storage_server.js @@ -1,5 +1,7 @@ /** - * Hachette storage through connection (server side) + * This file is part of Haketilo. + * + * Function: Storage through messages (server side). * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. diff --git a/background/stream_filter.js b/background/stream_filter.js index 96b6132..e5e0827 100644 --- a/background/stream_filter.js +++ b/background/stream_filter.js @@ -1,5 +1,7 @@ /** - * Hachette modifying a web page using the StreamFilter API + * This file is part of Haketilo. + * + * Function: Modifying a web page using the StreamFilter API. * * Copyright (C) 2018 Giorgio Maone <giorgio@maone.net> * Copyright (C) 2021 Wojtek Kosior @@ -12,7 +14,7 @@ /* * IMPORTS_START * IMPORT browser - * IMPORT is_csp_header_name + * IMPORT csp_header_regex * IMPORTS_END */ @@ -116,8 +118,7 @@ function may_define_csp_rules(html) const doc = new DOMParser().parseFromString(html, "text/html"); for (const meta of doc.querySelectorAll("head>meta[http-equiv]")) { - if (is_csp_header_name(meta.getAttribute("http-equiv"), true) && - meta.content) + if (csp_header_regex.test(meta.httpEquiv) && meta.content) return true; } @@ -174,7 +175,7 @@ function filter_data(properties, event) */ const dummy_script = - `<script data-hachette-deleteme="${properties.policy.nonce}" nonce="${properties.policy.nonce}">null</script>`; + `<script data-haketilo-deleteme="${properties.policy.nonce}" nonce="${properties.policy.nonce}">null</script>`; const doctype_decl = /^(\s*<!doctype[^<>"']*>)?/i.exec(decoded)[0]; decoded = doctype_decl + dummy_script + decoded.substring(doctype_decl.length); |