From 1814bfa03d090e7f0de7c68124c83fa3adacbfa5 Mon Sep 17 00:00:00 2001 From: hackademix Date: Tue, 4 Sep 2018 19:48:07 +0200 Subject: Work-around for CSP not being honored when the HEAD element has not been inserted yet. --- src/content/DocumentCSP.js | 20 ++++++++++++++------ src/content/content.js | 14 +------------- src/content/onScriptDisabled.js | 16 ---------------- 3 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/content/DocumentCSP.js b/src/content/DocumentCSP.js index 371e547..7fd666c 100644 --- a/src/content/DocumentCSP.js +++ b/src/content/DocumentCSP.js @@ -5,25 +5,33 @@ class DocumentCSP { this.document = document; this.builder = new CapsCSP(); } - + apply(capabilities, embedding = CSP.isEmbedType(this.document.contentType)) { let csp = this.builder; let blocker = csp.buildFromCapabilities(capabilities, embedding); if (!blocker) return; - + let document = this.document; + let createHTMLElement = + tagName => document.createElementNS("http://www.w3.org/1999/xhtml", tagName); + let header = csp.asHeader(blocker); - let meta = document.createElementNS("http://www.w3.org/1999/xhtml", "meta"); + let meta = createHTMLElement("meta"); meta.setAttribute("http-equiv", header.name); meta.setAttribute("content", header.value); - let parent = document.head || document.documentElement; + let parent = document.head || + document.documentElement.appendChild(createHTMLElement("head")); + try { parent.insertBefore(meta, parent.firstChild); debug(`Failsafe CSP inserted in the DOM: "%s"`, header.value); - if (capabilities.has("script")) meta.remove(); + if (capabilities.has("script")) { + meta.remove(); + if (!parent.firstChild) parent.remove(); + } } catch (e) { error(e, "Error inserting CSP %s in the DOM", header && header.value); } } - + } diff --git a/src/content/content.js b/src/content/content.js index fb68ae4..302ee8a 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -83,19 +83,7 @@ ns.on("capabilities", () => { }); if (!ns.canScript) { - addEventListener("beforescriptexecute", e => e.preventDefault()); - let mo = new MutationObserver(mutations => { - for (let m of mutations) { - console.log(`Mutation `, m); - if (m.type !== "attribute") continue; - if (/^on\w+/i.test(m.attributeName)) { - m.target.removeAttribute(m.attributeName); - } else if (/^\s*(javascript|data):/i.test(m.target.attributes[m.attributeName])) { - m.target.setAttribute(m.attributeName, "#"); - } - } - }); - // mo.observe(document.documentElement, {attributes: true, subtree: true}); + if ("serviceWorker" in navigator && navigator.serviceWorker.controller) { (async () => { for (let r of await navigator.serviceWorker.getRegistrations()) { diff --git a/src/content/onScriptDisabled.js b/src/content/onScriptDisabled.js index 79912c9..3606ede 100644 --- a/src/content/onScriptDisabled.js +++ b/src/content/onScriptDisabled.js @@ -1,20 +1,4 @@ function onScriptDisabled() { - if (document.URL.startsWith("file:")) { - // file: documents are loaded synchronously and may not be affected by - // CSP. We already intercept onbeforeexecutescript event, let's cope with - // event and URL attributes. - for (let e of document.all) { - for (let a of e.attributes) { - if (/^on\w+/i.test(a.name)) { - debug(`Removed %s.%sevent`, e.tagName, a.name); - a.value = ""; - } else if (/^\s*(?:data|javascript):/i.test(unescape(a.value))) { - debug(`Neutralized %s.%s="%s" attribute`, e.tagName, a.name, a.value); - a.value = "data:"; - } - } - } - } for (let noscript of document.querySelectorAll("noscript")) { // force show NOSCRIPT elements content let replacement = createHTMLElement("span"); -- cgit v1.2.3