diff options
-rw-r--r-- | background/policy_injector.js | 9 | ||||
-rw-r--r-- | common/gen_unique.js | 33 | ||||
-rw-r--r-- | common/misc.js | 59 | ||||
-rw-r--r-- | common/url_item.js | 19 | ||||
-rw-r--r-- | content/main.js | 15 |
5 files changed, 67 insertions, 68 deletions
diff --git a/background/policy_injector.js b/background/policy_injector.js index f05a422..4f70aac 100644 --- a/background/policy_injector.js +++ b/background/policy_injector.js @@ -14,6 +14,7 @@ * IMPORT gen_unique * IMPORT url_item * IMPORT get_query_best + * IMPORT csp_rule * IMPORTS_END */ @@ -40,16 +41,12 @@ function inject(details) if (settings !== undefined && settings.allow) return {cancel : false}; - let nonce = gen_unique(url).substring(1); + let nonce = gen_unique(url); let headers = details.responseHeaders.filter(is_noncsp_header); - let rule = `script-src 'nonce-${nonce}';`; - if (is_chrome) - rule += `script-src-elem 'nonce-${nonce}';`; - headers.push({ name : "content-security-policy", - value : rule + value : csp_rule(nonce) }); return {responseHeaders: headers}; diff --git a/common/gen_unique.js b/common/gen_unique.js deleted file mode 100644 index 7ec8b4a..0000000 --- a/common/gen_unique.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Myext generating unique, per-site hash - * - * Copyright (C) 2021 Wojtek Kosior - * Redistribution terms are gathered in the `copyright' file. - */ - -/* - * IMPORTS_START - * IMPORT sha256 - * IMPORT browser - * IMPORT is_chrome - * IMPORTS_END - */ - -function get_id() -{ - if (is_chrome) - return browser.runtime.getManifest().key.substring(0, 50); - else - return browser.runtime.getURL("dummy"); -} - -function gen_unique(url) -{ - return "#" + sha256(get_id() + url); -} - -/* - * EXPORTS_START - * EXPORT gen_unique - * EXPORTS_END - */ diff --git a/common/misc.js b/common/misc.js new file mode 100644 index 0000000..5754bd0 --- /dev/null +++ b/common/misc.js @@ -0,0 +1,59 @@ +/** + * Myext miscellaneous operations refactored to a separate file + * + * Copyright (C) 2021 Wojtek Kosior + * Redistribution terms are gathered in the `copyright' file. + */ + +/* + * IMPORTS_START + * IMPORT sha256 + * IMPORT browser + * IMPORT is_chrome + * IMPORTS_END + */ + +/* + * generating unique, per-site value that can be computed synchronously + * and is impossible to guess for a malicious website + */ +function gen_unique(url) +{ + return sha256(get_secure_salt() + url); +} + +function get_secure_salt() +{ + if (is_chrome) + return browser.runtime.getManifest().key.substring(0, 50); + else + return browser.runtime.getURL("dummy"); +} + +/* + * stripping url from query and target (everything after `#' or `?' + * gets removed) + */ +function url_item(url) +{ + let url_re = /^([^?#]*).*$/; + let match = url_re.exec(url); + return match[1]; +} + +/* csp rule that blocks all scripts except for those injected by us */ +function csp_rule(nonce) +{ + let rule = `script-src 'nonce-${nonce}';`; + if (is_chrome) + rule += `script-src-elem 'nonce-${nonce}';`; + return rule; +} + +/* + * EXPORTS_START + * EXPORT gen_unique + * EXPORT url_item + * EXPORT csp_rule + * EXPORTS_END + */ diff --git a/common/url_item.js b/common/url_item.js deleted file mode 100644 index 102f117..0000000 --- a/common/url_item.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Myext stripping url from query and target - * - * Copyright (C) 2021 Wojtek Kosior - * Redistribution terms are gathered in the `copyright' file. - */ - -function url_item(url) -{ - let url_re = /^([^?#]*).*$/; - let match = url_re.exec(url); - return match[1]; -} - -/* - * EXPORTS_START - * EXPORT url_item - * EXPORTS_END - */ diff --git a/content/main.js b/content/main.js index d55ee2e..8525961 100644 --- a/content/main.js +++ b/content/main.js @@ -10,6 +10,7 @@ * IMPORT handle_page_actions * IMPORT url_item * IMPORT gen_unique + * IMPORT csp_rule * IMPORT sanitize_attributes * IMPORT script_suppressor * IMPORT is_chrome @@ -30,9 +31,8 @@ let url = url_item(document.URL); let unique = gen_unique(url); -let nonce = unique.substring(1); -const suppressor = script_suppressor(nonce); +const suppressor = script_suppressor(unique); function needs_blocking() { @@ -46,7 +46,7 @@ function needs_blocking() let second_target = match[4]; if (first_target !== undefined && - first_target === unique) { + first_target === '#' + unique) { if (second_target !== undefined) window.location.href = base_url + second_target; else @@ -115,12 +115,7 @@ function inject_csp(head) let meta = document.createElement("meta"); meta.setAttribute("http-equiv", "Content-Security-Policy"); - - let rule = `script-src 'nonce-${nonce}'; `; - if (is_chrome) - rule += `script-src-elem 'nonce-${nonce}';`; - - meta.setAttribute("content", rule); + meta.setAttribute("content", csp_rule(unique)); if (head.firstElementChild === null) head.appendChild(meta); @@ -144,4 +139,4 @@ if (needs_blocking()) { addEventListener('beforescriptexecute', suppressor, true); } -handle_page_actions(nonce); +handle_page_actions(unique); |