Bug 1664999 - Added test for partitioned TLS peerIds. r=timhuang
authorPaul Zuehlcke <pbz@mozilla.com>
Mon, 23 Aug 2021 17:11:00 +0000
changeset 589594 d8565351ba24db542e63f488f576c888944c1e7e
parent 589593 d45ed8f7b1ccbe97d6b3f0743fc64daae47891e7
child 589595 c0f5b7db9f88b6ab917d82a9b8c10979e407901f
push id38729
push usercsabou@mozilla.com
push dateTue, 24 Aug 2021 03:18:22 +0000
treeherdermozilla-central@54e7fb66ad44 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstimhuang
bugs1664999
milestone93.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1664999 - Added test for partitioned TLS peerIds. r=timhuang Differential Revision: https://phabricator.services.mozilla.com/D123236
toolkit/components/antitracking/test/browser/browser.ini
toolkit/components/antitracking/test/browser/browser_staticPartition_tls_session.js
--- a/toolkit/components/antitracking/test/browser/browser.ini
+++ b/toolkit/components/antitracking/test/browser/browser.ini
@@ -159,16 +159,17 @@ support-files = browser_staticPartition_
 [browser_staticPartition_HSTS.js]
 support-files = browser_staticPartition_HSTS.sjs
 [browser_staticPartition_saveAs.js]
 support-files =
   file_saveAsImage.sjs
   file_saveAsVideo.sjs
   file_saveAsPageInfo.html
   file_video.ogv
+[browser_staticPartition_tls_session.js]
 [browser_staticPartition_websocket.js]
 skip-if =
   os == 'mac' && webrender && verify # Bug 1721210
 support-files =
   file_ws_handshake_delay_wsh.py
 [browser_partitionedClearSiteDataHeader.js]
 support-files =
   clearSiteData.sjs
new file mode 100644
--- /dev/null
+++ b/toolkit/components/antitracking/test/browser/browser_staticPartition_tls_session.js
@@ -0,0 +1,117 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+"use strict";
+
+/**
+ * Tests that we correctly partition TLS sessions by inspecting the
+ * socket's peerId. The peerId contains the OriginAttributes suffix which
+ * includes the partitionKey.
+ */
+
+const TEST_ORIGIN_A = "https://example.com";
+const TEST_ORIGIN_B = "https://example.org";
+const TEST_ORIGIN_C = "https://w3c-test.org";
+
+const TEST_ENDPOINT =
+  "/browser/toolkit/components/antitracking/test/browser/empty.js";
+
+const TEST_URL_C = TEST_ORIGIN_C + TEST_ENDPOINT;
+
+/**
+ * Waits for a load with the given URL to happen and returns the peerId.
+ * @param {string} url - The URL expected to load.
+ * @returns {Promise<string>} a promise which resolves on load with the
+ * associated socket peerId.
+ */
+async function waitForLoad(url) {
+  return new Promise(resolve => {
+    const TOPIC = "http-on-examine-response";
+
+    function observer(subject, topic, data) {
+      if (topic != TOPIC) {
+        return;
+      }
+      subject.QueryInterface(Ci.nsIChannel);
+      if (subject.URI.spec != url) {
+        return;
+      }
+
+      Services.obs.removeObserver(observer, TOPIC);
+
+      resolve(
+        subject.securityInfo.QueryInterface(Ci.nsISSLSocketControl).peerId
+      );
+    }
+    Services.obs.addObserver(observer, TOPIC);
+  });
+}
+
+/**
+ * Loads a url in the given browser and returns the tls socket's peer id
+ * associated with the load.
+ * Note: Loads are identified by URI. If multiple loads with the same URI happen
+ * concurrently, this method may not map them correctly.
+ * @param {MozBrowser} browser
+ * @param {string} url
+ * @returns {Promise<string>} Resolves on load with the peer id associated with
+ * the load.
+ */
+function loadURLInFrame(browser, url) {
+  let loadPromise = waitForLoad(url);
+  ContentTask.spawn(browser, [url], async testURL => {
+    let frame = content.document.createElement("iframe");
+    frame.src = testURL;
+    content.document.body.appendChild(frame);
+  });
+  return loadPromise;
+}
+
+add_task(async () => {
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      ["browser.cache.disk.enable", false],
+      ["browser.cache.memory.enable", false],
+      ["privacy.partition.network_state", true],
+      // The test harness acts as a proxy, so we need to make sure to also
+      // partition for proxies.
+      ["privacy.partition.network_state.connection_with_proxy", true],
+    ],
+  });
+
+  // C (first party)
+  let loadPromiseC = waitForLoad(TEST_URL_C);
+  await BrowserTestUtils.withNewTab(TEST_URL_C, async () => {});
+  let peerIdC = await loadPromiseC;
+
+  // C embedded in C (same origin)
+  let peerIdCC;
+  await BrowserTestUtils.withNewTab(TEST_ORIGIN_C, async browser => {
+    peerIdCC = await loadURLInFrame(browser, TEST_URL_C);
+  });
+
+  // C embedded in A (third party)
+  let peerIdAC;
+  await BrowserTestUtils.withNewTab(TEST_ORIGIN_A, async browser => {
+    peerIdAC = await loadURLInFrame(browser, TEST_URL_C);
+  });
+
+  // C embedded in B (third party)
+  let peerIdBC;
+  await BrowserTestUtils.withNewTab(TEST_ORIGIN_B, async browser => {
+    peerIdBC = await loadURLInFrame(browser, TEST_URL_C);
+  });
+
+  info("Test that top level load and same origin frame have the same peerId.");
+  is(peerIdC, peerIdCC, "Should have the same peerId");
+
+  info("Test that all partitioned peer ids are distinct.");
+  isnot(peerIdCC, peerIdAC, "Should have different peerId partitioned under A");
+  isnot(peerIdCC, peerIdBC, "Should have different peerId partitioned under B");
+  isnot(
+    peerIdAC,
+    peerIdBC,
+    "Should have a different peerId under different first parties."
+  );
+});