Work-around for applying DOM CSP to non-HTML XML documents (thanks skriptimaahinen).
This commit is contained in:
parent
52d97d29b8
commit
681d00ef84
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue