diff options
-rw-r--r-- | TODOS.org | 7 | ||||
-rw-r--r-- | background/policy_injector.js | 45 |
2 files changed, 35 insertions, 17 deletions
@@ -47,12 +47,11 @@ TODO: (e.g. file:// and ftp://) - Process HTML files in data: URLs instead of just blocking them - improve CSP injection for pathological cases like <script> before <head> -- Fix FF script blocking and whitelisting (FF seems to be by itself repeatedly - injecting CSP headers that were injected once, this makes it impossible to - whielist site that was unwhitelisted before; FF also seems to be removing our - injected script's nonce for no reason 🙁) DONE: +- Fix FF script whitelisting (FF seems to be by itself repeatedly -- DONE 2021-06-30 + injecting CSP headers that were injected once, this made it impossible to + whielist site that was unwhitelisted before) - find out if we can successfully use CSP to block file:// under FF -- DONE 2021-06-30 - come up with own simple DSL to manage imports/exports -- DONE 2021-06-30 - add some mechanism to build the extension -- DONE 2021-06-30 diff --git a/background/policy_injector.js b/background/policy_injector.js index 4f70aac..eb67963 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -21,33 +21,52 @@ var storage; var query_best; -let csp_header_names = { +const csp_header_names = { "content-security-policy" : true, "x-webkit-csp" : true, "x-content-security-policy" : true }; -function is_noncsp_header(header) +const header_name = "content-security-policy"; + +function is_csp_header(header) +{ + return !!csp_header_names[header.name.toLowerCase()]; +} + +function is_our_header(header, rule) { - return !csp_header_names[header.name.toLowerCase()]; + return header.value === rule } function inject(details) { - let url = url_item(details.url); + const url = url_item(details.url); + + const [pattern, settings] = query_best(url); + + const nonce = gen_unique(url); + const rule = csp_rule(nonce); - let [pattern, settings] = query_best(url); + var headers; - if (settings !== undefined && settings.allow) - return {cancel : false}; + if (settings !== undefined && settings.allow) { + /* + * Chrome doesn't have the buggy behavior of repeatedly injecting a + * header we injected once. Firefox does and we have to remove it there. + */ + if (is_chrome) + return {cancel: false}; - let nonce = gen_unique(url); - let headers = details.responseHeaders.filter(is_noncsp_header); + headers = details.responseHeaders.filter(h => !is_our_header(h, rule)); + } else { + headers = details.responseHeaders.filter(h => !is_csp_header(h)); - headers.push({ - name : "content-security-policy", - value : csp_rule(nonce) - }); + headers.push({ + name : header_name, + value : rule + }); + } return {responseHeaders: headers}; } |