From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../test/browser/browser_firstPartyIsolation.js | 511 +++++++++++++++++++++ 1 file changed, 511 insertions(+) create mode 100644 browser/components/originattributes/test/browser/browser_firstPartyIsolation.js (limited to 'browser/components/originattributes/test/browser/browser_firstPartyIsolation.js') diff --git a/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js b/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js new file mode 100644 index 0000000000..feec6550e3 --- /dev/null +++ b/browser/components/originattributes/test/browser/browser_firstPartyIsolation.js @@ -0,0 +1,511 @@ +const BASE_URL = + "https://example.net/browser/browser/components/originattributes/test/browser/"; +const EXAMPLE_BASE_URL = BASE_URL.replace("example.net", "example.com"); +const BASE_DOMAIN = "example.net"; + +add_setup(async function () { + Services.prefs.setBoolPref("privacy.firstparty.isolate", true); + registerCleanupFunction(function () { + Services.prefs.clearUserPref("privacy.firstparty.isolate"); + Services.cookies.removeAll(); + Services.cache2.clear(); + }); +}); + +/** + * Test for the top-level document and child iframes should have the + * firstPartyDomain attribute. + */ +add_task(async function principal_test() { + let tab = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "test_firstParty.html" + ); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, function (url) { + return url == BASE_URL + "test_firstParty.html"; + }); + + await SpecialPowers.spawn( + tab.linkedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + Assert.ok( + true, + "document principal: " + content.document.nodePrincipal.origin + ); + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + "", + "top-level docShell shouldn't have firstPartyDomain attribute." + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The document should have firstPartyDomain" + ); + + for (let i = 1; i < 4; i++) { + let iframe = content.document.getElementById("iframe" + i); + await SpecialPowers.spawn( + iframe, + [attrs.firstPartyDomain], + function (firstPartyDomain) { + Assert.ok( + true, + "iframe principal: " + content.document.nodePrincipal.origin + ); + + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + firstPartyDomain, + "iframe's docshell should have firstPartyDomain" + ); + + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + firstPartyDomain, + "iframe should have firstPartyDomain" + ); + } + ); + } + } + ); + + gBrowser.removeTab(tab); +}); + +/** + * Test for the cookie jars of the top-level document and child iframe should be + * isolated by firstPartyDomain. + */ +add_task(async function cookie_test() { + let tab = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "test_firstParty_cookie.html" + ); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser, true); + + let count = 0; + for (let cookie of Services.cookies.cookies) { + count++; + Assert.equal(cookie.value, "foo", "Cookie value should be foo"); + Assert.equal( + cookie.originAttributes.firstPartyDomain, + BASE_DOMAIN, + "Cookie's origin attributes should be " + BASE_DOMAIN + ); + } + + // one cookie is from requesting test.js from top-level doc, and the other from + // requesting test2.js from iframe test2.html. + Assert.equal(count, 2, "Should have two cookies"); + + gBrowser.removeTab(tab); +}); + +/** + * Test for after redirect, the top-level document should update the firstPartyDomain + * attribute. However if the redirect is happening on the iframe, the attribute + * should remain the same. + */ +add_task(async function redirect_test() { + let tab = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "test_firstParty_http_redirect.html" + ); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + await SpecialPowers.spawn( + tab.linkedBrowser, + [{ firstPartyDomain: "example.com" }], + async function (attrs) { + Assert.ok( + true, + "document principal: " + content.document.nodePrincipal.origin + ); + Assert.ok(true, "document uri: " + content.document.documentURI); + + Assert.equal( + content.document.documentURI, + "https://example.com/browser/browser/components/originattributes/test/browser/dummy.html", + "The page should have been redirected to https://example.com/browser/browser/components/originattributes/test/browser/dummy.html" + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The document should have firstPartyDomain" + ); + } + ); + + // Since this is a HTML redirect, we wait until the final page is loaded. + let tab2 = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "test_firstParty_html_redirect.html" + ); + await BrowserTestUtils.browserLoaded( + tab2.linkedBrowser, + false, + function (url) { + return url == "https://example.com/"; + } + ); + + await SpecialPowers.spawn( + tab2.linkedBrowser, + [{ firstPartyDomain: "example.com" }], + async function (attrs) { + Assert.ok( + true, + "2nd tab document principal: " + content.document.nodePrincipal.origin + ); + Assert.ok(true, "2nd tab document uri: " + content.document.documentURI); + Assert.equal( + content.document.documentURI, + "https://example.com/", + "The page should have been redirected to https://example.com" + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The document should have firstPartyDomain" + ); + } + ); + + let tab3 = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "test_firstParty_iframe_http_redirect.html" + ); + await BrowserTestUtils.browserLoaded( + tab3.linkedBrowser, + true, + function (url) { + return url == BASE_URL + "test_firstParty_iframe_http_redirect.html"; + } + ); + + // This redirect happens on the iframe, so unlike the two redirect tests above, + // the firstPartyDomain should still stick to the current top-level document, + // which is example.net. + await SpecialPowers.spawn( + tab3.linkedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + let iframe = content.document.getElementById("iframe1"); + SpecialPowers.spawn( + iframe, + [attrs.firstPartyDomain], + function (firstPartyDomain) { + Assert.ok( + true, + "iframe document principal: " + + content.document.nodePrincipal.origin + ); + Assert.ok( + true, + "iframe document uri: " + content.document.documentURI + ); + + Assert.equal( + content.document.documentURI, + "https://example.com/browser/browser/components/originattributes/test/browser/dummy.html", + "The page should have been redirected to https://example.com/browser/browser/components/originattributes/test/browser/dummy.html" + ); + + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + firstPartyDomain, + "The iframe should have firstPartyDomain: " + firstPartyDomain + ); + } + ); + } + ); + + gBrowser.removeTab(tab); + gBrowser.removeTab(tab2); + gBrowser.removeTab(tab3); +}); + +/** + * Test for postMessage between document and iframe. + */ +add_task(async function postMessage_test() { + let tab = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "test_firstParty_postMessage.html" + ); + + // The top-level page will post a message to its child iframe, and wait for + // another message from the iframe, once it receives the message, it will + // create another iframe, dummy.html. + // So we wait until dummy.html is loaded + await BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, function (url) { + return url == BASE_URL + "dummy.html"; + }); + + await SpecialPowers.spawn(tab.linkedBrowser, [], async function () { + Assert.ok( + true, + "document principal: " + content.document.nodePrincipal.origin + ); + let value = content.document.getElementById("message").textContent; + Assert.equal(value, "OK"); + }); + + gBrowser.removeTab(tab); +}); + +/** + * When the web page calls window.open, the new window should have the same + * firstPartyDomain attribute. + */ +add_task(async function openWindow_test() { + Services.prefs.setIntPref("browser.link.open_newwindow", 2); + registerCleanupFunction(function () { + Services.prefs.clearUserPref("browser.link.open_newwindow"); + }); + + let tab = BrowserTestUtils.addTab(gBrowser, BASE_URL + "window.html"); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + await SpecialPowers.spawn( + tab.linkedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + let promise = new Promise(resolve => { + content.addEventListener("message", resolve, { once: true }); + }); + let w = Cu.unwaiveXrays(content.wrappedJSObject.open()); + w.document.body.innerHTML = ``; + + await promise; + + Assert.equal( + w.docShell.getOriginAttributes().firstPartyDomain, + attrs.firstPartyDomain, + "window.open() should have correct firstPartyDomain attribute" + ); + Assert.equal( + w.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The document should have correct firstPartyDomain" + ); + + let iframe = w.document.getElementById("iframe1"); + await SpecialPowers.spawn( + iframe, + [attrs.firstPartyDomain], + function (firstPartyDomain) { + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + firstPartyDomain, + "iframe's docshell should have correct rirstPartyDomain" + ); + + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + firstPartyDomain, + "iframe should have correct firstPartyDomain" + ); + } + ); + + w.close(); + } + ); + + gBrowser.removeTab(tab); +}); + +/** + * When the web page calls window.open, the top-level docshell in the new + * created window will have firstPartyDomain set. + */ +add_task(async function window_open_redirect_test() { + Services.prefs.setIntPref("browser.link.open_newwindow", 2); + registerCleanupFunction(function () { + Services.prefs.clearUserPref("browser.link.open_newwindow"); + }); + + let tab = BrowserTestUtils.addTab( + gBrowser, + BASE_URL + "window_redirect.html" + ); + let win = await BrowserTestUtils.waitForNewWindow({ + url: BASE_URL + "dummy.html", + }); + + await SpecialPowers.spawn( + win.gBrowser.selectedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + attrs.firstPartyDomain, + "window.open() should have firstPartyDomain attribute" + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The document should have firstPartyDomain" + ); + } + ); + + gBrowser.removeTab(tab); + await BrowserTestUtils.closeWindow(win); +}); + +/** + * When the web page calls window.open, the top-level docshell in the new + * created window will inherit the firstPartyDomain attribute. + * However the top-level document will override the firstPartyDomain if the + * document is from another domain. + */ +add_task(async function window_open_iframe_test() { + Services.prefs.setIntPref("browser.link.open_newwindow", 2); + registerCleanupFunction(function () { + Services.prefs.clearUserPref("browser.link.open_newwindow"); + }); + + let tab = BrowserTestUtils.addTab(gBrowser, BASE_URL + "window2.html"); + let url = EXAMPLE_BASE_URL + "test_firstParty.html"; + info("Waiting for window with url " + url); + let win = await BrowserTestUtils.waitForNewWindow({ url }); + + await SpecialPowers.spawn( + win.gBrowser.selectedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + attrs.firstPartyDomain, + "window.open() should have firstPartyDomain attribute" + ); + + // The document is https://example.com/browser/browser/components/originattributes/test/browser/test_firstParty.html + // so the firstPartyDomain will be overriden to 'example.com'. + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + "example.com", + "The document should have firstPartyDomain" + ); + + let iframe = content.document.getElementById("iframe1"); + SpecialPowers.spawn(iframe, [], function () { + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + "example.com", + "iframe's docshell should have firstPartyDomain" + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + "example.com", + "iframe should have firstPartyDomain" + ); + }); + } + ); + + gBrowser.removeTab(tab); + await BrowserTestUtils.closeWindow(win); +}); + +/** + * Test for the loadInfo->TriggeringPrincipal is the document itself. + */ +add_task(async function form_test() { + let tab = BrowserTestUtils.addTab(gBrowser, BASE_URL + "test_form.html"); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + + await SpecialPowers.spawn( + tab.linkedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The document should have firstPartyDomain" + ); + + let submit = content.document.getElementById("submit"); + submit.click(); + } + ); + + gBrowser.removeTab(tab); +}); + +/** + * Another test for loadInfo->TriggeringPrincipal in the window.open case. + */ +add_task(async function window_open_form_test() { + Services.prefs.setIntPref("browser.link.open_newwindow", 2); + registerCleanupFunction(function () { + Services.prefs.clearUserPref("browser.link.open_newwindow"); + }); + + let tab = BrowserTestUtils.addTab(gBrowser, BASE_URL + "window3.html"); + let url = EXAMPLE_BASE_URL + "test_form.html"; + info("Waiting for window with url " + url); + let win = await BrowserTestUtils.waitForNewWindow({ url }); + + await SpecialPowers.spawn( + win.gBrowser.selectedBrowser, + [{ firstPartyDomain: BASE_DOMAIN }], + async function (attrs) { + Assert.equal( + content.docShell.getOriginAttributes().firstPartyDomain, + attrs.firstPartyDomain, + "window.open() should have firstPartyDomain attribute" + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + "example.com", + "The document should have firstPartyDomain" + ); + + let submit = content.document.getElementById("submit"); + submit.click(); + } + ); + + gBrowser.removeTab(tab); + await BrowserTestUtils.closeWindow(win); +}); + +/** + * A test for using an IP address as the first party domain. + */ +add_task(async function ip_address_test() { + const ipAddr = "127.0.0.1"; + const ipHost = `http://${ipAddr}/browser/browser/components/originattributes/test/browser/`; + + Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true); + registerCleanupFunction(function () { + Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost"); + }); + + let tab = BrowserTestUtils.addTab(gBrowser, ipHost + "test_firstParty.html"); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser, true); + + await SpecialPowers.spawn( + tab.linkedBrowser, + [{ firstPartyDomain: ipAddr }], + async function (attrs) { + Assert.ok( + true, + "document principal: " + content.document.nodePrincipal.origin + ); + Assert.equal( + content.document.nodePrincipal.originAttributes.firstPartyDomain, + attrs.firstPartyDomain, + "The firstPartyDomain should be set properly for the IP address" + ); + } + ); + + gBrowser.removeTab(tab); +}); -- cgit v1.2.3