From fa5c0b073214191e6996ba0b5bc8e61560ff822c Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 27 Sep 2023 00:53:30 -0400 Subject: Update the JShelter extension to 0.15.2. --- .../jsr@javascriptrestrictor/background.js | 63 ++++++++++++++++++++-- 1 file changed, 59 insertions(+), 4 deletions(-) (limited to 'data/extensions/jsr@javascriptrestrictor/background.js') diff --git a/data/extensions/jsr@javascriptrestrictor/background.js b/data/extensions/jsr@javascriptrestrictor/background.js index ab7cac9..019b76c 100644 --- a/data/extensions/jsr@javascriptrestrictor/background.js +++ b/data/extensions/jsr@javascriptrestrictor/background.js @@ -3,6 +3,7 @@ * * \author Copyright (C) 2019 Libor Polcak * \author Copyright (C) 2019 Martin Timko + * \author Copyright (C) 2023 Martin Zmitko * * \license SPDX-License-Identifier: GPL-3.0-or-later */ @@ -43,13 +44,62 @@ function tabUpdate(tabid, changeInfo) { if (url === undefined) { return wrapping_groups.empty_level; } - let current_level = getCurrentLevelJSON(url)[0]; + let current_level = getCurrentLevelJSON(url); tab_urls[tabid] = url; return current_level; } // on tab reload or tab change, update metadata browser.tabs.onUpdated.addListener(tabUpdate); // reload tab +const scriptSrcRegex = /script-src\s/; +// Modify CSP headers to allow WASM execution in page context +function cspRequestProcessor(details) { + // Because this handler fires before configuration for the page is created, + // we need to search for the configuration for that domain now. + let subDomains = extractSubDomains(getEffectiveDomain(details.url)); + let found = false; + for (let domain of subDomains.reverse()) { + if (domain in domains) { + found = true; + if (domains[domain].wasm !== 2) { + return {}; + } + break; + } + } + // If no configuration is found, use the default level. + if (!found && default_level.wasm !== 2) { + return {}; + } + + let modified = false; + let headers = details.responseHeaders; + for (let header of headers) { + let name = header.name.toLowerCase(); + if (name !== "content-security-policy" && + name !== "content-security-policy-report-only" && + name !== "x-webkit-csp") { + continue; + } + let origCSP = header.value; + header.value = header.value.replace(scriptSrcRegex, "script-src 'wasm-unsafe-eval' "); + if (origCSP !== header.value) { + modified = true; + } + } + return modified ? {responseHeaders: headers} : {}; +} +// Attach listener only in chromium where the WASM module is instantiated directly in +// page context, subject to the page's CSP. Code inserted as script tags isn't subject +// to script-src origins, it is, however, subject to the 'unsafe' group of script evaluation rules. +if (typeof browser_polyfill_used !== "undefined" && browser_polyfill_used) { + browser.webRequest.onHeadersReceived.addListener(cspRequestProcessor, + {urls: [""], + types: ["main_frame", "sub_frame"]}, + ["blocking", "responseHeaders"] + ); +} + // Communication channels /** @@ -61,9 +111,14 @@ browser.tabs.onUpdated.addListener(tabUpdate); // reload tab */ async function connected(port) { if (port.name === "port_from_popup") { - /// We always send back current level - let [tab] = await browser.tabs.query(queryInfo); - let current_level = tabUpdate(tab.id, tab.url); + let current_level = wrapping_groups.empty_level; + try { + // We always send back current level + let [tab] = await browser.tabs.query(queryInfo); + current_level = getCurrentLevelJSON(tab.url); + } catch (e) { + // Stick to the empty_level and ignore the exception + } port.postMessage(current_level); port.onMessage.addListener(function(msg) { port.postMessage(current_level); -- cgit v1.2.3