dom/security/test/mixedcontentblocker/test_main.html
author Kate McKinley <kmckinley@mozilla.com>
Tue, 27 Sep 2016 11:27:00 -0400
changeset 315476 380eebfd9d8928b656236d08e535fe528258e947
parent 306822 f0a977d25ead92214b82b776b3ded3f40a9e7c40
child 316208 82d198b87307cbd4c6f2ced19bee980d819877aa
permissions -rw-r--r--
Bug 1246540 - HSTS Priming Proof of Concept. r=ckerschb, r=mayhemer, r=jld, r=smaug, r=dkeeler, r=jmaher, p=ally HSTS priming changes the order of mixed-content blocking and HSTS upgrades, and adds a priming request to check if a mixed-content load is accesible over HTTPS and the server supports upgrading via the Strict-Transport-Security header. Every call site that uses AsyncOpen2 passes through the mixed-content blocker, and has a LoadInfo. If the mixed-content blocker marks the load as needing HSTS priming, nsHttpChannel will build and send an HSTS priming request on the same URI with the scheme upgraded to HTTPS. If the server allows the upgrade, then channel performs an internal redirect to the HTTPS URI, otherwise use the result of mixed-content blocker to allow or block the load. nsISiteSecurityService adds an optional boolean out parameter to determine if the HSTS state is already cached for negative assertions. If the host has been probed within the previous 24 hours, no HSTS priming check will be sent. MozReview-Commit-ID: ES1JruCtDdX

<!DOCTYPE HTML>
<html>
<!--
Tests for Mixed Content Blocker
https://bugzilla.mozilla.org/show_bug.cgi?id=62178
-->
<head>
  <meta charset="utf-8">
  <title>Tests for Bug 62178</title>
  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>

  <script>
  SpecialPowers.setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");

  var counter = 0;
  var settings = [ [true, true], [true, false], [false, true], [false, false] ];

  var blockActive;
  var blockDisplay;

  //Cycle through 4 different preference settings.
  function changePrefs(otherPrefs, callback) {
    let basePrefs = [["security.mixed_content.block_display_content", settings[counter][0]],
                     ["security.mixed_content.block_active_content", settings[counter][1]]];
    let newPrefs = basePrefs.concat(otherPrefs);

    SpecialPowers.pushPrefEnv({"set": newPrefs}, function () {
      blockDisplay = SpecialPowers.getBoolPref("security.mixed_content.block_display_content");
      blockActive = SpecialPowers.getBoolPref("security.mixed_content.block_active_content");
      counter++;
      callback();
    });
  }

  var testsToRun = {
    iframe: false,
    image: false,
    imageSrcset: false,
    imageSrcsetFallback: false,
    imagePicture: false,
    imageJoinPicture: false,
    imageLeavePicture: false,
    script: false,
    stylesheet: false,
    object: false,
    media: false,
    xhr: false,
  };

  function log(msg) {
    document.getElementById("log").textContent += "\n" + msg;
  }

  function reloadFrame() {
    document.getElementById('framediv').innerHTML = '<iframe id="testHarness" src="https://example.com/tests/dom/security/test/mixedcontentblocker/file_main.html"></iframe>';
  }

  function checkTestsCompleted() {
    for (var prop in testsToRun) {
      // some test hasn't run yet so we're not done
      if (!testsToRun[prop])
        return;
    }
    //if the testsToRun are all completed, chnage the pref and run the tests again until we have cycled through all the prefs.
    if(counter < 4) {
       for (var prop in testsToRun) {
         testsToRun[prop] = false;
       }
      //call to change the preferences
      changePrefs([], function() {
        log("\nblockDisplay set to "+blockDisplay+", blockActive set to "+blockActive+".");
        reloadFrame();
      });
    }
    else {
      SimpleTest.finish();
    }
  }

  var firstTest = true;

  function receiveMessage(event) {
    if(firstTest) {
      log("blockActive set to "+blockActive+", blockDisplay set to "+blockDisplay+".");
      firstTest = false;
    }

    log("test: "+event.data.test+", msg: "+event.data.msg + " logging message.");
    // test that the load type matches the pref for this type of content
    // (i.e. active vs. display)

    switch(event.data.test) {

      /* Mixed Script tests */
      case "iframe":
        ok(blockActive == (event.data.msg == "insecure iframe blocked"), "iframe did not follow block_active_content pref");
        testsToRun["iframe"] = true;
        break;

      case "object":
        ok(blockActive == (event.data.msg == "insecure object blocked"), "object did not follow block_active_content pref");
        testsToRun["object"] = true;
        break;

      case "script":
        ok(blockActive == (event.data.msg == "insecure script blocked"), "script did not follow block_active_content pref");
        testsToRun["script"] = true;
        break;

      case "stylesheet":
        ok(blockActive == (event.data.msg == "insecure stylesheet blocked"), "stylesheet did not follow block_active_content pref");
        testsToRun["stylesheet"] = true;
        break;

      case "xhr":
        ok(blockActive == (event.data.msg == "insecure xhr blocked"), "xhr did not follow block_active_content pref");
        testsToRun["xhr"] = true;
        break;

      /* Mixed Display tests */
      case "image":
        //test that the image load matches the pref for display content
        ok(blockDisplay == (event.data.msg == "insecure image blocked"), "image did not follow block_display_content pref");
        testsToRun["image"] = true;
        break;

      case "media":
        ok(blockDisplay == (event.data.msg == "insecure media blocked"), "media did not follow block_display_content pref");
        testsToRun["media"] = true;
        break;

      /* Images using the "imageset" policy, from <img srcset> and <picture>, do not get the mixed display exception */
      case "imageSrcset":
        ok(blockActive == (event.data.msg == "insecure image blocked"), "imageSrcset did not follow block_active_content pref");
        testsToRun["imageSrcset"] = true;
        break;

      case "imageSrcsetFallback":
        ok(blockActive == (event.data.msg == "insecure image blocked"), "imageSrcsetFallback did not follow block_active_content pref");
        testsToRun["imageSrcsetFallback"] = true;
        break;

      case "imagePicture":
        ok(blockActive == (event.data.msg == "insecure image blocked"), "imagePicture did not follow block_active_content pref");
        testsToRun["imagePicture"] = true;
        break;

      case "imageJoinPicture":
        ok(blockActive == (event.data.msg == "insecure image blocked"), "imageJoinPicture did not follow block_active_content pref");
        testsToRun["imageJoinPicture"] = true;
        break;

      // Should return to mixed display mode
      case "imageLeavePicture":
        ok(blockDisplay == (event.data.msg == "insecure image blocked"), "imageLeavePicture did not follow block_display_content pref");
        testsToRun["imageLeavePicture"] = true;
        break;

    }
    checkTestsCompleted();
  }

  function startTest() {
    // Set prefs to use mixed-content before HSTS
    SpecialPowers.pushPrefEnv({'set': [["security.mixed_content.use_hsts", false],
                                       ["security.mixed_content.send_hsts_priming", false]]});
    //Set the first set of mixed content settings and increment the counter.
    //Enable <picture> and <img srcset> for the test.
    changePrefs([[ "dom.image.srcset.enabled", true ], [ "dom.image.picture.enabled", true ]],
      function() {
        //listen for a messages from the mixed content test harness
        window.addEventListener("message", receiveMessage, false);

        //Kick off test
        reloadFrame();
      }
    );
  }

  SimpleTest.waitForExplicitFinish();

  </script>
</head>

<body onload='startTest()'>
  <div id="framediv"></div>
  <pre id="log"></pre>
</body>
</html>