From 538376341e9a50ebd350897fe26f43c433f0ee06 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 27 Aug 2021 10:01:32 +0200 Subject: enable whitelisting of `file://' protocol\n\nThis commit additionally also changes the semantics of triple asterisk wildcard in URL path. --- content/main.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 9 deletions(-) (limited to 'content/main.js') diff --git a/content/main.js b/content/main.js index 984b3cb..06d3bf1 100644 --- a/content/main.js +++ b/content/main.js @@ -10,6 +10,7 @@ * IMPORTS_START * IMPORT handle_page_actions * IMPORT extract_signed + * IMPORT sign_data * IMPORT gen_nonce * IMPORT is_privileged_url * IMPORT mozilla_suppress_scripts @@ -31,13 +32,13 @@ function accept_node(node, parent) parent.hachette_corresponding.appendChild(clone); } -if (!is_privileged_url(document.URL)) { - /* Signature valid for half an hour. */ - const min_time = new Date().getTime() - 1800 * 1000; +function extract_cookie_policy(cookie, min_time) +{ let best_result = {time: -1}; let policy = null; const extracted_signatures = []; - for (const match of document.cookie.matchAll(/hachette-(\w*)=([^;]*)/g)) { + + for (const match of cookie.matchAll(/hachette-(\w*)=([^;]*)/g)) { const new_result = extract_signed(...match.slice(1, 3)); if (new_result.fail) continue; @@ -56,17 +57,84 @@ if (!is_privileged_url(document.URL)) { policy = new_policy; } + return [policy, extracted_signatures]; +} + +function extract_url_policy(url, min_time) +{ + const [base_url, payload, anchor] = + /^([^#]*)#?([^#]*)(#?.*)$/.exec(url).splice(1, 4); + + const match = /^hachette_([^_]+)_(.*)$/.exec(payload); + if (!match) + return [null, url]; + + const result = extract_signed(...match.slice(1, 3)); + if (result.fail) + return [null, url]; + + const original_url = base_url + anchor; + const policy = result.time < min_time ? null : + JSON.parse(decodeURIComponent(result.data)); + + return [policy.url === original_url ? policy : null, original_url]; +} + +function employ_nonhttp_policy(policy) +{ + if (!policy.allow) + return; + + policy.nonce = gen_nonce(); + const [base_url, target] = /^([^#]*)(#?.*)$/.exec(policy.url).slice(1, 3); + const encoded_policy = encodeURIComponent(JSON.stringify(policy)); + const payload = "hachette_" + + sign_data(encoded_policy, new Date().getTime()).join("_"); + const resulting_url = `${base_url}#${payload}${target}`; + location.href = resulting_url; + location.reload(); +} + +if (!is_privileged_url(document.URL)) { + let policy_received_callback = () => undefined; + let policy; + + /* Signature valid for half an hour. */ + const min_time = new Date().getTime() - 1800 * 1000; + + if (/^https?:/.test(document.URL)) { + let signatures; + [policy, signatures] = extract_cookie_policy(document.cookie, min_time); + for (const signature of signatures) + document.cookie = `hachette-${signature}=; Max-Age=-1;`; + } else { + const scheme = /^([^:]*)/.exec(document.URL)[1]; + const known_scheme = ["file"].includes(scheme); + + if (!known_scheme) + console.warn(`Unknown url scheme: \`${scheme}'!`); + + let original_url; + [policy, original_url] = extract_url_policy(document.URL, min_time); + history.replaceState(null, "", original_url); + + if (known_scheme && !policy) + policy_received_callback = employ_nonhttp_policy; + } + if (!policy) { - console.warn("WARNING! Using default policy!!!"); + console.warn("Using default policy!"); policy = {allow: false, nonce: gen_nonce()}; } - for (const signature of extracted_signatures) - document.cookie = `hachette-${signature}=; Max-Age=-1;`; - - handle_page_actions(policy.nonce); + handle_page_actions(policy.nonce, policy_received_callback); if (!policy.allow) { + if (is_mozilla) { + const script = document.querySelector("script"); + if (script) + script.textContent = "throw 'blocked';\n" + script.textContent; + } const old_html = document.documentElement; const new_html = document.createElement("html"); old_html.replaceWith(new_html); -- cgit v1.2.3