/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* * Tests the persistence of the "disable protection" option for Mixed Content * Blocker in child tabs (bug 906190). */ requestLongerTimeout(2); // We use the different urls for testing same origin checks before allowing // mixed content on child tabs. const HTTPS_TEST_ROOT_1 = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://test1.example.com" ); const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace( "chrome://mochitests/content", "https://test2.example.com" ); /** * For all tests, we load the pages over HTTPS and test both: * - |CTRL+CLICK| * - |RIGHT CLICK -> OPEN LINK IN TAB| */ async function doTest( parentTabSpec, childTabSpec, testTaskFn, waitForMetaRefresh ) { await BrowserTestUtils.withNewTab( { gBrowser, url: parentTabSpec, }, async function (browser) { // As a sanity check, test that active content has been blocked as expected. await assertMixedContentBlockingState(gBrowser, { activeLoaded: false, activeBlocked: true, passiveLoaded: false, }); // Disable the Mixed Content Blocker for the page, which reloads it. let promiseReloaded = BrowserTestUtils.browserLoaded(browser); let principal = gBrowser.contentPrincipal; gIdentityHandler.disableMixedContentProtection(); await promiseReloaded; // Wait for the script in the page to update the contents of the test div. await SpecialPowers.spawn( browser, [childTabSpec], async childTabSpecContent => { let testDiv = content.document.getElementById("mctestdiv"); await ContentTaskUtils.waitForCondition( () => testDiv.innerHTML == "Mixed Content Blocker disabled" ); // Add the link for the child tab to the page. let mainDiv = content.document.createElement("div"); // eslint-disable-next-line no-unsanitized/property mainDiv.innerHTML = '

Link

'; content.document.body.appendChild(mainDiv); } ); // Execute the test in the child tabs with the two methods to open it. for (let openFn of [simulateCtrlClick, simulateContextMenuOpenInTab]) { let promiseTabLoaded = waitForSomeTabToLoad(); openFn(browser); await promiseTabLoaded; gBrowser.selectTabAtIndex(2); if (waitForMetaRefresh) { await waitForSomeTabToLoad(); } await testTaskFn(); gBrowser.removeCurrentTab(); } SitePermissions.removeFromPrincipal(principal, "mixed-content"); } ); } function simulateCtrlClick(browser) { BrowserTestUtils.synthesizeMouseAtCenter( "#linkToOpenInNewTab", { ctrlKey: true, metaKey: true }, browser ); } function simulateContextMenuOpenInTab(browser) { BrowserTestUtils.waitForEvent(document, "popupshown", false, event => { // These are operations that must be executed synchronously with the event. document.getElementById("context-openlinkintab").doCommand(); event.target.hidePopup(); return true; }); BrowserTestUtils.synthesizeMouseAtCenter( "#linkToOpenInNewTab", { type: "contextmenu", button: 2 }, browser ); } // Waits for a load event somewhere in the browser but ignore events coming // from s without a tab assigned. That are most likely browsers // that preload the new tab page. function waitForSomeTabToLoad() { return BrowserTestUtils.firstBrowserLoaded(window, true, browser => { let tab = gBrowser.getTabForBrowser(browser); return !!tab; }); } /** * Ensure the Mixed Content Blocker is enabled. */ add_task(async function test_initialize() { await SpecialPowers.pushPrefEnv({ set: [ ["security.mixed_content.block_active_content", true], // We need to disable the dFPI heuristic. So, we won't have unnecessary // 3rd party cookie permission that could affect following tests because // it will create a permission icon on the URL bar. ["privacy.restrict3rdpartystorage.heuristic.recently_visited", false], ], }); }); /** * 1. - Load a html page which has mixed content * - Doorhanger to disable protection appears - we disable it * - Load a subpage from the same origin in a new tab simulating a click * - Doorhanger should >> NOT << appear anymore! */ add_task(async function test_same_origin() { await doTest( HTTPS_TEST_ROOT_1 + "file_bug906190_1.html", HTTPS_TEST_ROOT_1 + "file_bug906190_2.html", async function () { // The doorhanger should appear but activeBlocked should be >> NOT << true, // because our decision of disabling the mixed content blocker is persistent // across tabs. await assertMixedContentBlockingState(gBrowser, { activeLoaded: true, activeBlocked: false, passiveLoaded: false, }); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { Assert.equal( content.document.getElementById("mctestdiv").innerHTML, "Mixed Content Blocker disabled", "OK: Executed mixed script" ); }); } ); }); /** * 2. - Load a html page which has mixed content * - Doorhanger to disable protection appears - we disable it * - Load a new page from a different origin in a new tab simulating a click * - Doorhanger >> SHOULD << appear again! */ add_task(async function test_different_origin() { await doTest( HTTPS_TEST_ROOT_1 + "file_bug906190_2.html", HTTPS_TEST_ROOT_2 + "file_bug906190_2.html", async function () { // The doorhanger should appear and activeBlocked should be >> TRUE <<, // because our decision of disabling the mixed content blocker should only // persist if pages are from the same domain. await assertMixedContentBlockingState(gBrowser, { activeLoaded: false, activeBlocked: true, passiveLoaded: false, }); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { Assert.equal( content.document.getElementById("mctestdiv").innerHTML, "Mixed Content Blocker enabled", "OK: Blocked mixed script" ); }); } ); }); /** * 3. - Load a html page which has mixed content * - Doorhanger to disable protection appears - we disable it * - Load a new page from the same origin in a new tab simulating a click * - Redirect to another page from the same origin using meta-refresh * - Doorhanger should >> NOT << appear again! */ add_task(async function test_same_origin_metarefresh_same_origin() { // file_bug906190_3_4.html redirects to page test1.example.com/* using meta-refresh await doTest( HTTPS_TEST_ROOT_1 + "file_bug906190_1.html", HTTPS_TEST_ROOT_1 + "file_bug906190_3_4.html", async function () { // The doorhanger should appear but activeBlocked should be >> NOT << true! await assertMixedContentBlockingState(gBrowser, { activeLoaded: true, activeBlocked: false, passiveLoaded: false, }); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { Assert.equal( content.document.getElementById("mctestdiv").innerHTML, "Mixed Content Blocker disabled", "OK: Executed mixed script" ); }); }, true ); }); /** * 4. - Load a html page which has mixed content * - Doorhanger to disable protection appears - we disable it * - Load a new page from the same origin in a new tab simulating a click * - Redirect to another page from a different origin using meta-refresh * - Doorhanger >> SHOULD << appear again! */ add_task(async function test_same_origin_metarefresh_different_origin() { await doTest( HTTPS_TEST_ROOT_2 + "file_bug906190_1.html", HTTPS_TEST_ROOT_2 + "file_bug906190_3_4.html", async function () { // The doorhanger should appear and activeBlocked should be >> TRUE <<. await assertMixedContentBlockingState(gBrowser, { activeLoaded: false, activeBlocked: true, passiveLoaded: false, }); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { Assert.equal( content.document.getElementById("mctestdiv").innerHTML, "Mixed Content Blocker enabled", "OK: Blocked mixed script" ); }); }, true ); }); /** * 5. - Load a html page which has mixed content * - Doorhanger to disable protection appears - we disable it * - Load a new page from the same origin in a new tab simulating a click * - Redirect to another page from the same origin using 302 redirect */ add_task(async function test_same_origin_302redirect_same_origin() { // the sjs files returns a 302 redirect- note, same origins await doTest( HTTPS_TEST_ROOT_1 + "file_bug906190_1.html", HTTPS_TEST_ROOT_1 + "file_bug906190.sjs", async function () { // The doorhanger should appear but activeBlocked should be >> NOT << true. // Currently it is >> TRUE << - see follow up bug 914860 ok( !gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"), "OK: Mixed Content is NOT being blocked" ); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { Assert.equal( content.document.getElementById("mctestdiv").innerHTML, "Mixed Content Blocker disabled", "OK: Executed mixed script" ); }); } ); }); /** * 6. - Load a html page which has mixed content * - Doorhanger to disable protection appears - we disable it * - Load a new page from the same origin in a new tab simulating a click * - Redirect to another page from a different origin using 302 redirect */ add_task(async function test_same_origin_302redirect_different_origin() { // the sjs files returns a 302 redirect - note, different origins await doTest( HTTPS_TEST_ROOT_2 + "file_bug906190_1.html", HTTPS_TEST_ROOT_2 + "file_bug906190.sjs", async function () { // The doorhanger should appear and activeBlocked should be >> TRUE <<. await assertMixedContentBlockingState(gBrowser, { activeLoaded: false, activeBlocked: true, passiveLoaded: false, }); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { Assert.equal( content.document.getElementById("mctestdiv").innerHTML, "Mixed Content Blocker enabled", "OK: Blocked mixed script" ); }); } ); }); /** * 7. - Test memory leak issue on redirection error. See Bug 1269426. */ add_task(async function test_bad_redirection() { // the sjs files returns a 302 redirect - note, different origins await doTest( HTTPS_TEST_ROOT_2 + "file_bug906190_1.html", HTTPS_TEST_ROOT_2 + "file_bug906190.sjs?bad-redirection=1", function () { // Nothing to do. Just see if memory leak is reported in the end. ok(true, "Nothing to do"); } ); });