summaryrefslogtreecommitdiff
path: root/data/extensions/jsr@javascriptrestrictor/background.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/jsr@javascriptrestrictor/background.js')
-rw-r--r--data/extensions/jsr@javascriptrestrictor/background.js63
1 files changed, 59 insertions, 4 deletions
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: ["<all_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);