From ecb787046271de708b94da70240713e725299d86 Mon Sep 17 00:00:00 2001 From: jahoti Date: Sun, 18 Jul 2021 00:00:00 +0000 Subject: Streamline and harden unique values/settings The base URL is now included in the settings. The unique value no longer uses it directly, as it is included by virtue of the settings; however, the number of full hours since the epoch (UTC) is now incorporated. --- background/policy_injector.js | 21 +++++++++++++-------- common/misc.js | 34 ++++++++++++++++++++++++++-------- content/main.js | 2 +- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/background/policy_injector.js b/background/policy_injector.js index 8a767fb..2cd7b6e 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -17,6 +17,7 @@ * IMPORT gen_nonce * IMPORT url_item * IMPORT url_extract_policy + * IMPORT sign_policy * IMPORT get_query_best * IMPORT csp_rule * IMPORTS_END @@ -46,7 +47,7 @@ function is_our_header(header, rule) function url_inject(details) { const targets = url_extract_policy(details.url); - if (targets.valid_sig) { + if (targets.current) { return; } else if (targets.policy) { /* Redirect; update policy */ @@ -59,11 +60,16 @@ function url_inject(details) /* Defaults */ settings = {}; - const policy = {allow: settings.allow, nonce: gen_nonce()}; - const policy_string = encodeURIComponent(JSON.stringify(policy)); - const sig = gen_unique(policy_string + targets.base_url); + const policy = encodeURIComponent( + JSON.stringify({ + allow: settings.allow, + nonce: gen_nonce(), + base_url: targets.base_url + }) + ); - let redirect_url = targets.base_url + '#' + sig + policy_string; + let redirect_url = targets.base_url; + redirect_url += '#' + sign_policy(policy, new Date()) + policy; if (targets.target) redirect_url += targets.target; if (targets.target2) @@ -75,12 +81,11 @@ function url_inject(details) function inject(details) { const targets = url_extract_policy(details.url); - if (!targets.valid_sig) - /* Block unsigned requests */ + if (!targets.current) + /* Block mis-/unsigned requests */ return {cancel: true}; const rule = csp_rule(targets.policy.nonce); - var headers = details.responseHeaders; if (!targets.policy.allow || is_mozilla) diff --git a/common/misc.js b/common/misc.js index 036eb45..472620e 100644 --- a/common/misc.js +++ b/common/misc.js @@ -104,23 +104,40 @@ function is_privileged_url(url) return !!/^(chrome(-extension)?|moz-extension):\/\/|^about:/i.exec(url); } +/* Sign a given policy for a given time */ +function sign_policy(policy, now, hours_offset) { + let time = Math.floor(now / 3600000) + (hours_offset || 0); + return gen_unique(time + policy); +} + /* Extract any policy present in the URL */ function url_extract_policy(url) { - var policy_string; const targets = url_extract_target(url); + if (!targets.target) + return targets; + + /* %7B -> { */ + const index = targets.target.indexOf('%7B'); + if (index === -1) + return targets; + + const now = new Date(); + const sig = targets.target.substring(1, index); + const policy = targets.target.substring(index); + if ( + sig !== sign_policy(policy, now) && + sig !== sign_policy(policy, now, -1) && + sig !== sign_policy(policy, now, 1) + ) + return targets; try { - policy_string = targets.target.substring(65); - targets.policy = JSON.parse(decodeURIComponent(policy_string)); + targets.policy = JSON.parse(decodeURIComponent(policy)); + targets.current = targets.policy.base_url === targets.base_url; } catch (e) { /* TODO what should happen here? */ } - - if (targets.policy) { - const sig = gen_unique(policy_string + targets.base_url); - targets.valid_sig = targets.target.substring(1, 65) === sig; - } return targets; } @@ -132,6 +149,7 @@ function url_extract_policy(url) * EXPORT url_item * EXPORT url_extract_target * EXPORT url_extract_policy + * EXPORT sign_policy * EXPORT csp_rule * EXPORT nice_name * EXPORT open_in_settings diff --git a/content/main.js b/content/main.js index 317b319..a5e04fd 100644 --- a/content/main.js +++ b/content/main.js @@ -107,7 +107,7 @@ if (!is_privileged_url(document.URL)) { history.replaceState(null, "", targets.base_url); } - targets.policy = targets.valid_sig ? targets.policy : {}; + targets.policy = targets.current ? targets.policy : {}; const nonce = targets.policy.nonce || gen_nonce(); start_activity_info_server(); -- cgit v1.2.3