Work-around for applying DOM CSP to non-HTML XML documents (thanks skriptimaahinen).

This commit is contained in:
hackademix 2020-09-04 15:05:58 +02:00
parent 52d97d29b8
commit 681d00ef84
2 changed files with 24 additions and 9 deletions

View File

@ -25,19 +25,38 @@ class DocumentCSP {
tagName => document.createElementNS("http://www.w3.org/1999/xhtml", tagName); tagName => document.createElementNS("http://www.w3.org/1999/xhtml", tagName);
let header = csp.asHeader(blocker); let header = csp.asHeader(blocker);
let meta = createHTMLElement("meta"); let meta = createHTMLElement("meta");
meta.setAttribute("http-equiv", header.name); meta.setAttribute("http-equiv", header.name);
meta.setAttribute("content", header.value); meta.setAttribute("content", header.value);
let root = document.documentElement; let root = document.documentElement;
let {head} = document;
let parent = head || document.documentElement.appendChild(createHTMLElement("head"))
try { try {
if (!(document instanceof HTMLDocument)) {
// non-HTML XML documents ignore <meta> CSP unless wrapped in
// - <html><head></head></head> on Gecko
// - just <head></head> on Chromium
console.debug("XML Document: temporary replacing %o with <HTML>", 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); parent.insertBefore(meta, parent.firstElementChild);
debug(`Failsafe <meta> CSP inserted in %s: "%s"`, document.URL, header.value); debug(`Failsafe <meta> CSP inserted in %s: "%s"`, document.URL, header.value);
meta.remove(); meta.remove();
if (!head) parent.remove(); if (!head) parent.remove();
if (document.documentElement !== root)
{
document.replaceChild(root, document.documentElement);
}
} catch (e) { } catch (e) {
error(e, "Error inserting CSP %s in %s", document.URL, header && header.value); error(e, "Error inserting CSP %s in %s", document.URL, header && header.value);
return false; return false;

View File

@ -25,13 +25,9 @@
let {readyState} = document; let {readyState} = document;
debug("Readystate: %s, suppressedScripts = %s, canScript = %s", readyState, DocumentFreezer.suppressedScripts, ns.canScript); 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 (!ns.canScript) {
if (honorsCSP) { setTimeout(() => DocumentFreezer.unfreeze(), 0);
DocumentFreezer.unfreeze();
}
return; return;
} }