/** * 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: [""], types: ["main_frame", "sub_frame"] }, extra_opts ); } window.start_policy_injector = start; })();