forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D59691 --HG-- extra : moz-landing-system : lando
203 lines
6 KiB
JavaScript
203 lines
6 KiB
JavaScript
function isIsolated(key) {
|
|
return key.charAt(7) == "i";
|
|
}
|
|
|
|
function hasTopWindowOrigin(key, origin) {
|
|
let tokenAtEnd = `{{${origin}}}`;
|
|
let endPart = key.slice(-tokenAtEnd.length);
|
|
return endPart == tokenAtEnd;
|
|
}
|
|
|
|
function hasAnyTopWindowOrigin(key) {
|
|
return !!key.match(/{{[^}]+}}/);
|
|
}
|
|
|
|
function altSvcCacheKeyIsolated(parsed) {
|
|
return parsed.length > 5 && parsed[5] == "I";
|
|
}
|
|
|
|
function altSvcTopWindowOrigin(key) {
|
|
let index = -1;
|
|
for (let i = 0; i < 6; ++i) {
|
|
index = key.indexOf(":", index + 1);
|
|
}
|
|
let indexEnd = key.indexOf("|", index + 1);
|
|
return key.substring(index + 1, indexEnd);
|
|
}
|
|
|
|
const gHttpHandler = Cc["@mozilla.org/network/protocol;1?name=http"].getService(
|
|
Ci.nsIHttpProtocolHandler
|
|
);
|
|
|
|
add_task(async function() {
|
|
info("Starting tlsSessionTickets test");
|
|
|
|
await SpecialPowers.flushPrefEnv();
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [
|
|
["browser.cache.disk.enable", false],
|
|
["browser.cache.memory.enable", false],
|
|
[
|
|
"network.cookie.cookieBehavior",
|
|
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
|
|
],
|
|
["network.http.altsvc.proxy_checks", false],
|
|
["privacy.trackingprotection.enabled", false],
|
|
["privacy.trackingprotection.pbmode.enabled", false],
|
|
["privacy.trackingprotection.annotate_channels", true],
|
|
],
|
|
});
|
|
|
|
await UrlClassifierTestUtils.addTestTrackers();
|
|
|
|
info("Creating a new tab");
|
|
let tab = BrowserTestUtils.addTab(gBrowser, TEST_TOP_PAGE);
|
|
gBrowser.selectedTab = tab;
|
|
|
|
let browser = gBrowser.getBrowserForTab(tab);
|
|
await BrowserTestUtils.browserLoaded(browser);
|
|
|
|
const trackingURL =
|
|
"https://tlsresumptiontest.example.org/browser/toolkit/components/antitracking/test/browser/empty-altsvc.js";
|
|
const topWindowOrigin = TEST_DOMAIN.replace(/\/$/, "");
|
|
const kTopic = "http-on-examine-response";
|
|
|
|
let resumedState = [];
|
|
let hashKeys = [];
|
|
|
|
function observer(subject, topic, data) {
|
|
if (topic != kTopic) {
|
|
return;
|
|
}
|
|
|
|
subject.QueryInterface(Ci.nsIChannel);
|
|
if (subject.URI.spec != trackingURL) {
|
|
return;
|
|
}
|
|
|
|
resumedState.push(
|
|
subject.securityInfo.QueryInterface(Ci.nsISSLSocketControl).resumed
|
|
);
|
|
hashKeys.push(
|
|
subject.QueryInterface(Ci.nsIHttpChannelInternal).connectionInfoHashKey
|
|
);
|
|
}
|
|
|
|
Services.obs.addObserver(observer, kTopic);
|
|
registerCleanupFunction(() => Services.obs.removeObserver(observer, kTopic));
|
|
|
|
function checkAltSvcCache(expectedCount, expectedIsolated) {
|
|
let arr = gHttpHandler.altSvcCacheKeys;
|
|
is(
|
|
arr.length,
|
|
expectedCount,
|
|
"Found the expected number of items in the cache"
|
|
);
|
|
for (let i = 0; i < arr.length; ++i) {
|
|
let key = arr[i];
|
|
let parsed = key.split(":");
|
|
if (altSvcCacheKeyIsolated(parsed)) {
|
|
ok(expectedIsolated[i], "We expected to find an isolated item");
|
|
is(
|
|
altSvcTopWindowOrigin(key),
|
|
topWindowOrigin,
|
|
"Expected top window origin found in the Alt-Svc cache key"
|
|
);
|
|
} else {
|
|
ok(!expectedIsolated[i], "We expected to find a non-isolated item");
|
|
}
|
|
}
|
|
}
|
|
|
|
checkAltSvcCache(0, []);
|
|
|
|
info("Loading tracking scripts and tracking images");
|
|
await SpecialPowers.spawn(browser, [{ trackingURL }], async function(obj) {
|
|
let src = content.document.createElement("script");
|
|
let p = new content.Promise(resolve => {
|
|
src.onload = resolve;
|
|
});
|
|
content.document.body.appendChild(src);
|
|
src.src = obj.trackingURL;
|
|
await p;
|
|
});
|
|
|
|
checkAltSvcCache(1, [true]);
|
|
|
|
// Load our tracking URL two more times, but this time in the first-party context.
|
|
// The TLS session should be resumed the second time here.
|
|
await fetch(trackingURL);
|
|
// Wait a little bit before issuing the second load to ensure both don't happen
|
|
// at the same time.
|
|
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
|
|
await new Promise(resolve => setTimeout(resolve, 10));
|
|
|
|
checkAltSvcCache(2, [false, true]);
|
|
await fetch(trackingURL).then(() => {
|
|
checkAltSvcCache(2, [false, true]);
|
|
|
|
is(
|
|
resumedState.length,
|
|
3,
|
|
"We should have observed 3 loads for " + trackingURL
|
|
);
|
|
ok(!resumedState[0], "The first load should NOT have been resumed");
|
|
ok(!resumedState[1], "The second load should NOT have been resumed");
|
|
ok(resumedState[2], "The third load SHOULD have been resumed");
|
|
|
|
// We also verify that the hashKey of the first connection is different to
|
|
// both the second and third connections, and that the hashKey of the
|
|
// second and third connections are the same. The reason why this check is
|
|
// done is that the private bit on the connection info object is used to
|
|
// construct the hash key, so when the connection is isolated because it
|
|
// comes from a third-party tracker context, its hash key must be
|
|
// different.
|
|
is(
|
|
hashKeys.length,
|
|
3,
|
|
"We should have observed 3 loads for " + trackingURL
|
|
);
|
|
is(hashKeys[1], hashKeys[2], "The second and third hash keys should match");
|
|
isnot(
|
|
hashKeys[0],
|
|
hashKeys[1],
|
|
"The first and second hash keys should not match"
|
|
);
|
|
|
|
ok(isIsolated(hashKeys[0]), "The first connection must have been isolated");
|
|
ok(
|
|
!isIsolated(hashKeys[1]),
|
|
"The second connection must not have been isolated"
|
|
);
|
|
ok(
|
|
!isIsolated(hashKeys[2]),
|
|
"The third connection must not have been isolated"
|
|
);
|
|
ok(
|
|
hasTopWindowOrigin(hashKeys[0], topWindowOrigin),
|
|
"The first connection must be bound to its top-level window"
|
|
);
|
|
ok(
|
|
!hasAnyTopWindowOrigin(hashKeys[1]),
|
|
"The second connection must not be bound to a top-level window"
|
|
);
|
|
ok(
|
|
!hasAnyTopWindowOrigin(hashKeys[2]),
|
|
"The third connection must not be bound to a top-level window"
|
|
);
|
|
});
|
|
|
|
info("Removing the tab");
|
|
BrowserTestUtils.removeTab(tab);
|
|
|
|
UrlClassifierTestUtils.cleanupTestTrackers();
|
|
});
|
|
|
|
add_task(async function() {
|
|
info("Cleaning up.");
|
|
await new Promise(resolve => {
|
|
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, value =>
|
|
resolve()
|
|
);
|
|
});
|
|
});
|