diff options
-rw-r--r-- | background/policy_injector.js | 29 | ||||
-rw-r--r-- | common/misc.js | 26 | ||||
-rw-r--r-- | content/main.js | 11 |
3 files changed, 32 insertions, 34 deletions
diff --git a/background/policy_injector.js b/background/policy_injector.js index 9e8ed61..8a767fb 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -12,6 +12,7 @@ * IMPORT get_storage * IMPORT browser * IMPORT is_chrome + * IMPORT is_mozilla * IMPORT gen_unique * IMPORT gen_nonce * IMPORT url_item @@ -45,23 +46,24 @@ function is_our_header(header, rule) function url_inject(details) { const targets = url_extract_policy(details.url); - if (targets.policy) { + if (targets.valid_sig) { return; - } else if (targets.signed) { + } else if (targets.policy) { /* Redirect; update policy */ targets.target = targets.target2; delete targets.target2 } - let redirect_url = targets.base_url + targets.sig; let [pattern, settings] = query_best(targets.base_url); if (!pattern) /* 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); - redirect_url += encodeURIComponent(JSON.stringify(policy)); + let redirect_url = targets.base_url + '#' + sig + policy_string; if (targets.target) redirect_url += targets.target; if (targets.target2) @@ -73,31 +75,26 @@ function url_inject(details) function inject(details) { const targets = url_extract_policy(details.url); - if (!targets.policy) + if (!targets.valid_sig) /* Block unsigned requests */ return {cancel: true}; const rule = csp_rule(targets.policy.nonce); - var headers; + var headers = details.responseHeaders; - if (targets.policy.allow) { + if (!targets.policy.allow || is_mozilla) /* - * Chrome doesn't have the buggy behavior of repeatedly injecting a - * header we injected once. Firefox does and we have to remove it there. + * Chrome doesn't have the buggy behavior of caching headers + * we injected. Firefox does and we have to remove it there. */ - if (is_chrome) - return {cancel: false}; - - headers = details.responseHeaders.filter(h => !is_our_header(h, rule)); - } else { - headers = details.responseHeaders.filter(h => !is_csp_header(h)); + headers = headers.filter(h => !is_csp_header(h)); + if (!targets.policy.allow) headers.push({ name : header_name, value : rule }); - } return {responseHeaders: headers}; } diff --git a/common/misc.js b/common/misc.js index 825a117..036eb45 100644 --- a/common/misc.js +++ b/common/misc.js @@ -35,9 +35,9 @@ function gen_unique(url) function get_secure_salt() { if (is_chrome) - return browser.runtime.getManifest().key.substring(0, 36); + return browser.runtime.getManifest().key.substring(0, 50); else - return browser.runtime.getURL("dummy").substr(16, 36); + return browser.runtime.getURL("dummy"); } /* @@ -107,19 +107,19 @@ function is_privileged_url(url) /* Extract any policy present in the URL */ function url_extract_policy(url) { + var policy_string; const targets = url_extract_target(url); - const key = '#' + get_secure_salt(); - targets.sig = key + gen_unique(targets.base_url); - if (targets.target && targets.target.startsWith(key)) { - targets.signed = true; - if (targets.target.startsWith(targets.sig)) - try { - const policy_string = targets.target.substring(101); - targets.policy = JSON.parse(decodeURIComponent(policy_string)); - } catch (e) { - /* TODO what should happen here? */ - } + try { + policy_string = targets.target.substring(65); + targets.policy = JSON.parse(decodeURIComponent(policy_string)); + } 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; diff --git a/content/main.js b/content/main.js index e75f61d..317b319 100644 --- a/content/main.js +++ b/content/main.js @@ -100,15 +100,16 @@ function inject_csp(head) if (!is_privileged_url(document.URL)) { const targets = url_extract_policy(document.URL); - targets.policy = targets.policy || {}; - const nonce = targets.policy.nonce || gen_nonce(); - - if (targets.signed) + if (targets.policy) { if (targets.target2 !== undefined) window.location.href = targets.base_url + targets.target2; else history.replaceState(null, "", targets.base_url); - + } + + targets.policy = targets.valid_sig ? targets.policy : {}; + + const nonce = targets.policy.nonce || gen_nonce(); start_activity_info_server(); handle_page_actions(nonce); |