From 261548ff184926567a623e90df7954aeef842d59 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 30 Jun 2021 12:28:05 +0200 Subject: emply an sh-based build system; make some changes to blocking --- content/freezer.js | 98 ++++++++++----------- content/main.js | 221 ++++++++++++++++++++++++++---------------------- content/page_actions.js | 92 ++++++++++---------- 3 files changed, 218 insertions(+), 193 deletions(-) (limited to 'content') diff --git a/content/freezer.js b/content/freezer.js index cdd0709..1696f53 100644 --- a/content/freezer.js +++ b/content/freezer.js @@ -6,58 +6,60 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; +const loaderAttributes = ["href", "src", "data"]; +const jsOrDataUrlRx = /^(?:data:(?:[^,;]*ml|unknown-content-type)|javascript:)/i; -(() => { - const loaderAttributes = ["href", "src", "data"]; - const jsOrDataUrlRx = /^(?:data:(?:[^,;]*ml|unknown-content-type)|javascript:)/i; +function sanitize_attributes(element) { + if (element._frozen) + return; + let fa = []; + let loaders = []; + let attributes = element.attributes || []; - function sanitizeAttributes(element) { - if (element._frozen) - return; - let fa = []; - let loaders = []; - for (let a of element.attributes) { - let name = a.localName.toLowerCase(); - if (loaderAttributes.includes(name)) - if (jsOrDataUrlRx.test(a.value)) - loaders.push(a); + for (let a of attributes) { + let name = a.localName.toLowerCase(); + if (loaderAttributes.includes(name)) + if (jsOrDataUrlRx.test(a.value)) + loaders.push(a); - else if (name.startsWith("on")) { - console.debug("Removing", a, element.outerHTML); - fa.push(a.cloneNode()); - a.value = ""; - element[name] = null; - } + else if (name.startsWith("on")) { + console.debug("Removing", a, element.outerHTML); + fa.push(a.cloneNode()); + a.value = ""; + element[name] = null; } - if (loaders.length) { - for (let a of loaders) { - fa.push(a.cloneNode()); - a.value = "javascript://frozen"; - } - if ("contentWindow" in element) - element.replaceWith(element = element.cloneNode(true)); - + } + if (loaders.length) { + for (let a of loaders) { + fa.push(a.cloneNode()); + a.value = "javascript://frozen"; } - if (fa.length) - element._frozenAttributes = fa; - element._frozen = true; + if ("contentWindow" in element) + element.replaceWith(element = element.cloneNode(true)); + } - - function scriptSuppressor(nonce) { - const blockExecute = e => { - if (document.readyState === 'complete') { - removeEventListener('beforescriptexecute', blockExecute, true); - return; - } - else if (e.isTrusted && e.target.getAttribute('nonce') !== nonce) { // Prevent blocking of injected scripts - e.preventDefault(); - console.log('Suppressed script', e.target); - } - }; - return blockExecute; + if (fa.length) + element._frozenAttributes = fa; + element._frozen = true; +} + +function script_suppressor(nonce) { + const blockExecute = e => { + if (document.readyState === 'complete') { + removeEventListener('beforescriptexecute', blockExecute, true); + return; + } + else if (e.isTrusted && e.target.getAttribute('nonce') !== nonce) { // Prevent blocking of injected scripts + e.preventDefault(); + console.log('Suppressed script', e.target); + } }; - - window.scriptSuppressor = scriptSuppressor; - window.sanitize_attributes = sanitizeAttributes; -})(); + return blockExecute; +}; + +/* + * EXPORTS_START + * EXPORT script_suppressor + * EXPORT sanitize_attributes + * EXPORTS_END + */ diff --git a/content/main.js b/content/main.js index 2a46c7e..d55ee2e 100644 --- a/content/main.js +++ b/content/main.js @@ -5,113 +5,133 @@ * Redistribution terms are gathered in the `copyright' file. */ -"use strict"; +/* + * IMPORTS_START + * IMPORT handle_page_actions + * IMPORT url_item + * IMPORT gen_unique + * IMPORT sanitize_attributes + * IMPORT script_suppressor + * IMPORT is_chrome + * IMPORT is_mozilla + * IMPORTS_END + */ -(() => { - const handle_page_actions = window.handle_page_actions; - const url_item = window.url_item; - const gen_unique = window.gen_unique; - const sanitize_attributes = window.sanitize_attributes; +/* + * Due to some technical limitations the chosen method of whitelisting sites + * is to smuggle whitelist indicator in page's url as a "magical" string + * after '#'. Right now this is not needed in HTTP(s) pages where native + * script blocking happens through CSP header injection but is needed for + * protocols like ftp:// and file://. + * + * The code that actually injects the magical string into ftp:// and file:// + * urls has not yet been added to the extension. + */ - /* - * Due to some technical limitations the chosen method of whitelisting sites - * is to smuggle whitelist indicator in page's url as a "magical" string - * after '#'. Right now this is not needed in HTTP(s) pages where native - * script blocking happens through CSP header injection but is needed for - * protocols like ftp:// and file://. - * - * The code that actually injects the magical string into ftp:// and file:// - * urls has not yet been added to the extension. - */ +let url = url_item(document.URL); +let unique = gen_unique(url); +let nonce = unique.substring(1); - let url = url_item(document.URL); - let unique = gen_unique(url); - let nonce = unique.substring(1); - - const scriptSuppressor = window.scriptSuppressor(nonce); - - function needs_blocking() - { - if (url.startsWith("https://") || url.startsWith("http://")) - return false; - - let url_re = /^([^#]*)((#[^#]*)(#.*)?)?$/; - let match = url_re.exec(document.URL); - let base_url = match[1]; - let first_target = match[3]; - let second_target = match[4]; - - if (first_target !== undefined && - first_target === unique) { - if (second_target !== undefined) - window.location.href = base_url + second_target; - else - history.replaceState(null, "", base_url); - - console.log(["allowing whitelisted", document.URL]); - return false; - } - - console.log(["disallowing", document.URL]); - return true; - } +const suppressor = script_suppressor(nonce); + +function needs_blocking() +{ + if (url.startsWith("https://") || url.startsWith("http://")) + return false; - function handle_mutation(mutations, observer) - { - if (document.readyState === 'complete') { - console.log("complete"); - observer.disconnect(); - return; - } - for (let mutation of mutations) { - for (let node of mutation.addedNodes) { - /* - * Modifying