author Kris Maglione <>
Wed, 24 Jan 2018 14:56:48 -0800
changeset 454546 64737c752ac4af4766ad6f82720818521f3aca24
parent 238779 2db29c0ae60b6eb0e196165631127d195fe2ef0b
permissions -rw-r--r--
Bug 1432966: Sanitize HTML fragments created for chrome-privileged documents. r=bz f=gijs a=jcristau This is a short-term solution to our inability to apply CSP to chrome-privileged documents. Ideally, we should be preventing all inline script execution in chrome-privileged documents, since the reprecussions of XSS in chrome documents are much worse than in content documents. Unfortunately, that's not possible in the near term because a) we don't support CSP in system principal documents at all, and b) we rely heavily on inline JS in our static XUL. This stop-gap solution at least prevents some of the most common vectors of XSS attack, by automatically sanitizing any HTML fragment created for a chrome-privileged document. MozReview-Commit-ID: 5w17celRFr

<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<window title="Mozilla Bug 683852"
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
  <button value="testbutton" id="testbutton"/>
  <!-- test results are displayed in the html:body -->
  <body xmlns="">
  <a href=""
     target="_blank" id="link">Mozilla Bug 683852</a>

  <!-- test code goes here -->
  <script type="application/javascript">
  /** Test for Bug 683852 **/

  const NS_HTML = "";

  function startTest() {
    is(document.contains(document), true, "Document should contain itself!");

    var tb = document.getElementById("testbutton");
    is(document.contains(tb), true, "Document should contain element in it!");
    is(tb.contains(tb), true, "Element should contain itself.")
    var anon = document.getAnonymousElementByAttribute(tb, "anonid", "button-box");
    is(document.contains(anon), false, "Document should not contain anonymous element in it!");
    is(tb.contains(anon), false, "Element should not contain anonymous element in it!");
    is(anon.contains(anon), true, "Anonymous element should contain itself.")
    is(document.documentElement.contains(tb), true, "Element should contain element in it!");
    is(document.contains(document.createElement("foo")), false, "Document shouldn't contain element which is't in the document");
    is(document.contains(document.createTextNode("foo")), false, "Document shouldn't contain text node which is't in the document");

    var link = document.getElementById("link");
    is(document.contains(link.firstChild), true,
       "Document should contain a text node in it.");
    is(link.contains(link.firstChild), true,
       "Element should contain a text node in it.");
    is(link.firstChild.contains(link), false, "text node shouldn't contain its parent.");

    is(document.contains(null), false, "Document shouldn't contain null.");

    var pi = document.createProcessingInstruction("adf", "asd");
    is(pi.contains(document), false, "Processing instruction shouldn't contain document");
    document.contains(pi, true, "Document should contain processing instruction");

    var df = document.createRange().createContextualFragment(`<div xmlns="${NS_HTML}">foo</div>`);
    is(df.contains(df.firstChild), true, "Document fragment should contain its child");
    is(df.contains(df.firstChild.firstChild), true,
       "Document fragment should contain its descendant");
    is(df.contains(df), true, "Document fragment should contain itself.");

    var d = document.implementation.createHTMLDocument("");
    is(document.contains(d), false,
       "Document shouldn't contain another document.");
    is(document.contains(d.createElement("div")), false,
       "Document shouldn't contain an element from another document.");