diff options
Diffstat (limited to 'background/policy_injector.js')
-rw-r--r-- | background/policy_injector.js | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/background/policy_injector.js b/background/policy_injector.js new file mode 100644 index 0000000..e2d6358 --- /dev/null +++ b/background/policy_injector.js @@ -0,0 +1,93 @@ +/** + * Myext injecting policy to page using webRequest + * + * Copyright (C) 2021 Wojtek Kosior + * + * This code is dual-licensed under: + * - Asshole license 1.0, + * - GPLv3 or (at your option) any later version + * + * "dual-licensed" means you can choose the license you prefer. + * + * This code is released under a permissive license because I disapprove of + * copyright and wouldn't be willing to sue a violator. Despite not putting + * this code under copyleft (which is also kind of copyright), I do not want + * it to be made proprietary. Hence, the permissive alternative to GPL is the + * Asshole license 1.0 that allows me to call you an asshole if you use it. + * This means you're legally ok regardless of how you utilize this code but if + * you make it into something nonfree, you're an asshole. + * + * You should have received a copy of both GPLv3 and Asshole license 1.0 + * together with this code. If not, please see: + * - https://www.gnu.org/licenses/gpl-3.0.en.html + * - https://koszko.org/asshole-license.txt + */ + +"use strict"; + +(() => { + const TYPE_PREFIX = window.TYPE_PREFIX; + const get_storage = window.get_storage; + const browser = window.browser; + const is_chrome = window.is_chrome; + const gen_unique = window.gen_unique; + const url_item = window.url_item; + const get_query_best = window.get_query_best; + + var storage; + var query_best; + + let csp_header_names = { + "content-security-policy" : true, + "x-webkit-csp" : true, + "x-content-security-policy" : true + }; + + function is_noncsp_header(header) + { + return !csp_header_names[header.name.toLowerCase()]; + } + + function inject(details) + { + let url = url_item(details.url); + + let [pattern, settings] = query_best(url); + + if (settings !== undefined && settings.allow) { + console.log("allowing", url); + return {cancel : false}; + } + + let nonce = gen_unique(url).substring(1); + let headers = details.responseHeaders.filter(is_noncsp_header); + headers.push({ + name : "content-security-policy", + value : `script-src 'nonce-${nonce}'; script-src-elem 'nonce-${nonce}';` + }); + + console.log("modified headers", url, headers); + + return {responseHeaders: headers}; + } + + async function start() { + storage = await get_storage(); + query_best = await get_query_best(); + + let extra_opts = ["blocking", "responseHeaders"]; + if (is_chrome) + extra_opts.push("extraHeaders"); + + browser.webRequest.onHeadersReceived.addListener( + inject, + { + urls: ["<all_urls>"], + types: ["main_frame", "sub_frame"] + }, + extra_opts + ); + } + + window.start_policy_injector = start; +})(); |