dom/serviceworkers/test/test_third_party_iframes.html
author Andrea Marchesini <amarchesini@mozilla.com>
Wed, 27 Feb 2019 19:57:47 +0000
changeset 519391 6a8401de32379f23a5544a7e0b5b1b16916fd581
parent 519097 bc51c190590a057206eb960e3eca6ac7461c36a3
child 519419 66a4a5cb3fc7603baa4fe83c98b3b83b5b33075c
permissions -rw-r--r--
Bug 1525245 - Stabilize cookiePolicy/cookiePermission for live documents - part 10 - Fix existing tests, r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D18958

<!--
  Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
  <title>Bug 1152899 - Disallow the interception of third-party iframes using service workers when the third-party cookie preference is set</title>
  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">

SimpleTest.waitForExplicitFinish();
SimpleTest.requestLongerTimeout(2);

let index = 0;
function next() {
  info("Step " + index);
  if (index >= steps.length) {
    SimpleTest.finish();
    return;
  }
  try {
    let i = index++;
    steps[i]();
  } catch(ex) {
    ok(false, "Caught exception", ex);
  }
}

onload = next;

let iframe;
let proxyWindow;
let basePath = "/tests/dom/serviceworkers/test/thirdparty/";
let origin = window.location.protocol + "//" + window.location.host;
let thirdPartyOrigin = "https://example.com";

function testIframeLoaded() {
  ok(true, "Iframe loaded");
  iframe.removeEventListener("load", testIframeLoaded);
  let message = {
    source: "parent",
    href: origin + basePath + "iframe2.html"
  };
  iframe.contentWindow.postMessage(message.toSource(), "*");
}

function loadThirdPartyIframe() {
  let message = {
    source: "parent",
    href: thirdPartyOrigin + basePath + "iframe2.html"
  }
  iframe.contentWindow.postMessage(message.toSource(), "*");
}

function runTest(aExpectedResponses) {
  // Let's use a proxy window to have the new cookie policy applied.
  proxyWindow = window.open("window_party_iframes.html");
  proxyWindow.onload = _ => {
    iframe = proxyWindow.document.querySelector("iframe");
    iframe.src = thirdPartyOrigin + basePath + "register.html";
    let responsesIndex = 0;
    window.onmessage = function(e) {
      let status = e.data.status;
      let expected = aExpectedResponses[responsesIndex];
      if (status == expected.status) {
        ok(true, "Received expected " + expected.status);
        if (expected.next) {
          expected.next();
        }
      } else {
        ok(false, "Expected " + expected.status + " got " + status);
      }
      responsesIndex++;
    };
  }
}

// Verify that we can register and intercept a 3rd party iframe with
// the given cookie policy.
function testShouldIntercept(behavior, lifetime, done) {
  SpecialPowers.pushPrefEnv({"set": [
      ["network.cookie.cookieBehavior", behavior],
      ["network.cookie.lifetimePolicy", lifetime],
  ]}, function() {
    runTest([{
      status: "ok"
    }, {
      status: "registrationdone",
      next: function() {
        iframe.addEventListener("load", testIframeLoaded);
        iframe.src = origin + basePath + "iframe1.html";
      }
    }, {
      status: "networkresponse",
    }, {
      status: "worker-networkresponse",
      next: loadThirdPartyIframe
    }, {
      status: "swresponse",
    }, {
      status: "worker-swresponse",
      next: function() {
        iframe.src = thirdPartyOrigin + basePath + "unregister.html";
      }
    }, {
      status: "controlled",
    }, {
      status: "unregistrationdone",
      next: function() {
        window.onmessage = null;
        proxyWindow.close();
        ok(true, "Test finished successfully");
        done();
      }
    }]);
  });
}

// Verify that we cannot register a service worker in a 3rd party
// iframe with the given cookie policy.
function testShouldNotRegister(behavior, lifetime, done) {
  SpecialPowers.pushPrefEnv({"set": [
      ["network.cookie.cookieBehavior", behavior],
      ["network.cookie.lifetimePolicy", lifetime],
  ]}, function() {
    runTest([{
      status: "registrationfailed",
      next: function() {
        iframe.addEventListener("load", testIframeLoaded);
        iframe.src = origin + basePath + "iframe1.html";
      }
    }, {
      status: "networkresponse",
    }, {
      status: "worker-networkresponse",
      next: loadThirdPartyIframe
    }, {
      status: "networkresponse",
    }, {
      status: "worker-networkresponse",
      next: function() {
        window.onmessage = null;
        proxyWindow.close();
        ok(true, "Test finished successfully");
        done();
      }
    }]);
  });
}

// Verify that if a service worker is already registered a 3rd
// party iframe will still not be intercepted with the given cookie
// policy.
function testShouldNotIntercept(behavior, lifetime, done) {
  SpecialPowers.pushPrefEnv({"set": [
    ["network.cookie.cookieBehavior", BEHAVIOR_ACCEPT],
    ["network.cookie.lifetimePolicy", LIFETIME_EXPIRE],
  ]}, function() {
    runTest([{
      status: "ok"
    }, {
      status: "registrationdone",
      next: function() {
        SpecialPowers.pushPrefEnv({"set": [
            ["network.cookie.cookieBehavior", behavior],
            ["network.cookie.lifetimePolicy", lifetime],
          ]}, function() {
            proxyWindow.close();
            proxyWindow = window.open("window_party_iframes.html");
            proxyWindow.onload = _ => {
              iframe = proxyWindow.document.querySelector("iframe");
              iframe.addEventListener("load", testIframeLoaded);
              iframe.src = origin + basePath + "iframe1.html";
            }
          });
      }
    }, {
      status: "networkresponse",
    }, {
      status: "worker-networkresponse",
      next: loadThirdPartyIframe
    }, {
      status: "networkresponse",
    }, {
      status: "worker-networkresponse",
      next: function() {
        iframe.src = thirdPartyOrigin + basePath + "unregister.html";
      }
    }, {
      status: "uncontrolled",
    }, {
      status: "getregistrationfailed",
      next: function() {
        SpecialPowers.pushPrefEnv({"set": [
            ["network.cookie.cookieBehavior", BEHAVIOR_ACCEPT],
            ["network.cookie.lifetimePolicy", LIFETIME_EXPIRE],
          ]}, function() {
            proxyWindow.close();
            proxyWindow = window.open("window_party_iframes.html");
            proxyWindow.onload = _ => {
              iframe = proxyWindow.document.querySelector("iframe");
              iframe.addEventListener("load", testIframeLoaded);
              iframe.src = thirdPartyOrigin + basePath + "unregister.html";
            }
          });
      }
    }, {
      status: "controlled",
    }, {
      status: "unregistrationdone",
      next: function() {
        window.onmessage = null;
        proxyWindow.close();
        ok(true, "Test finished successfully");
        done();
      }
    }]);
  });
}

const BEHAVIOR_ACCEPT        = 0;
const BEHAVIOR_REJECTFOREIGN = 1;
const BEHAVIOR_REJECT        = 2;
const BEHAVIOR_LIMITFOREIGN  = 3;

const LIFETIME_EXPIRE        = 0;
const LIFETIME_SESSION       = 2;

let steps = [() => {
  SpecialPowers.pushPrefEnv({"set": [
    ["dom.serviceWorkers.exemptFromPerDomainMax", true],
    ["dom.serviceWorkers.enabled", true],
    ["dom.serviceWorkers.testing.enabled", true],
    ["browser.dom.window.dump.enabled", true],
    ["network.cookie.cookieBehavior", BEHAVIOR_ACCEPT],
    ["network.cookie.lifetimePolicy", LIFETIME_EXPIRE],
  ]}, next);
}, () => {
  testShouldIntercept(BEHAVIOR_ACCEPT, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotRegister(BEHAVIOR_REJECTFOREIGN, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_REJECTFOREIGN, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotRegister(BEHAVIOR_REJECT, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_REJECT, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotRegister(BEHAVIOR_LIMITFOREIGN, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_LIMITFOREIGN, LIFETIME_EXPIRE, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_ACCEPT, LIFETIME_SESSION, next);
}, () => {
  testShouldNotRegister(BEHAVIOR_REJECTFOREIGN, LIFETIME_SESSION, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_REJECTFOREIGN, LIFETIME_SESSION, next);
}, () => {
  testShouldNotRegister(BEHAVIOR_REJECT, LIFETIME_SESSION, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_REJECT, LIFETIME_SESSION, next);
}, () => {
  testShouldNotRegister(BEHAVIOR_LIMITFOREIGN, LIFETIME_SESSION, next);
}, () => {
  testShouldNotIntercept(BEHAVIOR_LIMITFOREIGN, LIFETIME_SESSION, next);
}];

</script>
</pre>
</body>
</html>