From 681d00ef8480ca2508b2abcaf9edbdb43e4597f1 Mon Sep 17 00:00:00 2001 From: hackademix Date: Fri, 4 Sep 2020 15:05:58 +0200 Subject: [PATCH] Work-around for applying DOM CSP to non-HTML XML documents (thanks skriptimaahinen). --- src/content/DocumentCSP.js | 27 +++++++++++++++++++++++---- src/content/syncFetchPolicy.js | 6 +----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/content/DocumentCSP.js b/src/content/DocumentCSP.js index 47358f3..0dd9279 100644 --- a/src/content/DocumentCSP.js +++ b/src/content/DocumentCSP.js @@ -25,19 +25,38 @@ class DocumentCSP { tagName => document.createElementNS("http://www.w3.org/1999/xhtml", tagName); let header = csp.asHeader(blocker); + let meta = createHTMLElement("meta"); meta.setAttribute("http-equiv", header.name); meta.setAttribute("content", header.value); + let root = document.documentElement; - - let {head} = document; - let parent = head || document.documentElement.appendChild(createHTMLElement("head")) - try { + if (!(document instanceof HTMLDocument)) { + // non-HTML XML documents ignore CSP unless wrapped in + // - on Gecko + // - just on Chromium + console.debug("XML Document: temporary replacing %o with ", root); + let htmlDoc = document.implementation.createHTMLDocument(); + let htmlRoot = document.importNode(htmlDoc.documentElement, true); + document.replaceChild(htmlRoot, root); + } + + let {head} = document; + let parent = head || + document.documentElement.insertBefore(createHTMLElement("head"), + document.documentElement.firstElementChild); + + parent.insertBefore(meta, parent.firstElementChild); debug(`Failsafe CSP inserted in %s: "%s"`, document.URL, header.value); meta.remove(); if (!head) parent.remove(); + if (document.documentElement !== root) + { + + document.replaceChild(root, document.documentElement); + } } catch (e) { error(e, "Error inserting CSP %s in %s", document.URL, header && header.value); return false; diff --git a/src/content/syncFetchPolicy.js b/src/content/syncFetchPolicy.js index dca0a85..141e783 100644 --- a/src/content/syncFetchPolicy.js +++ b/src/content/syncFetchPolicy.js @@ -25,13 +25,9 @@ let {readyState} = document; debug("Readystate: %s, suppressedScripts = %s, canScript = %s", readyState, DocumentFreezer.suppressedScripts, ns.canScript); - // CSP works on HTML documents only on Mozilla: we'll keep frozen elsewhere - let honorsCSP = document instanceof HTMLDocument; if (!ns.canScript) { - if (honorsCSP) { - DocumentFreezer.unfreeze(); - } + setTimeout(() => DocumentFreezer.unfreeze(), 0); return; }