diff options
Diffstat (limited to 'browser/components/safebrowsing/content')
7 files changed, 366 insertions, 0 deletions
diff --git a/browser/components/safebrowsing/content/test/browser.ini b/browser/components/safebrowsing/content/test/browser.ini new file mode 100644 index 0000000000..f213bcee79 --- /dev/null +++ b/browser/components/safebrowsing/content/test/browser.ini @@ -0,0 +1,10 @@ +[DEFAULT] +support-files = + head.js + empty_file.html + +[browser_bug400731.js] +[browser_bug415846.js] +skip-if = true # Bug 1248632 +[browser_mixedcontent_aboutblocked.js] +[browser_whitelisted.js] diff --git a/browser/components/safebrowsing/content/test/browser_bug400731.js b/browser/components/safebrowsing/content/test/browser_bug400731.js new file mode 100644 index 0000000000..39a048198b --- /dev/null +++ b/browser/components/safebrowsing/content/test/browser_bug400731.js @@ -0,0 +1,65 @@ +/* Check presence of the "Ignore this warning" button */ + +function checkWarningState() { + return SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + return !!content.document.getElementById("ignore_warning_link"); + }); +} + +add_task(async function testMalware() { + await new Promise(resolve => waitForDBInit(resolve)); + + await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); + + const url = "http://www.itisatrap.org/firefox/its-an-attack.html"; + BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, url); + await BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + url, + true + ); + + let buttonPresent = await checkWarningState(); + ok(buttonPresent, "Ignore warning link should be present for malware"); +}); + +add_task(async function testUnwanted() { + Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", false); + + // Now launch the unwanted software test + const url = "http://www.itisatrap.org/firefox/unwanted.html"; + BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, url); + await BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + url, + true + ); + + // Confirm that "Ignore this warning" is visible - bug 422410 + let buttonPresent = await checkWarningState(); + ok( + !buttonPresent, + "Ignore warning link should be missing for unwanted software" + ); +}); + +add_task(async function testPhishing() { + Services.prefs.setBoolPref("browser.safebrowsing.allowOverride", true); + + // Now launch the phishing test + const url = "http://www.itisatrap.org/firefox/its-a-trap.html"; + BrowserTestUtils.loadURIString(gBrowser.selectedBrowser, url); + await BrowserTestUtils.browserLoaded( + gBrowser.selectedBrowser, + false, + url, + true + ); + + let buttonPresent = await checkWarningState(); + ok(buttonPresent, "Ignore warning link should be present for phishing"); + + gBrowser.removeCurrentTab(); +}); diff --git a/browser/components/safebrowsing/content/test/browser_bug415846.js b/browser/components/safebrowsing/content/test/browser_bug415846.js new file mode 100644 index 0000000000..a75332850b --- /dev/null +++ b/browser/components/safebrowsing/content/test/browser_bug415846.js @@ -0,0 +1,98 @@ +/* Check for the correct behaviour of the report web forgery/not a web forgery +menu items. + +Mac makes this astonishingly painful to test since their help menu is special magic, +but we can at least test it on the other platforms.*/ + +const NORMAL_PAGE = "http://example.com"; +const PHISH_PAGE = "http://www.itisatrap.org/firefox/its-a-trap.html"; + +/** + * Opens a new tab and browses to some URL, tests for the existence + * of the phishing menu items, and then runs a test function to check + * the state of the menu once opened. This function will take care of + * opening and closing the menu. + * + * @param url (string) + * The URL to browse the tab to. + * @param testFn (function) + * The function to run once the menu has been opened. This + * function will be passed the "reportMenu" and "errorMenu" + * DOM nodes as arguments, in that order. This function + * should not yield anything. + * @returns Promise + */ +function check_menu_at_page(url, testFn) { + return BrowserTestUtils.withNewTab( + { + gBrowser, + url: "about:blank", + }, + async function (browser) { + // We don't get load events when the DocShell redirects to error + // pages, but we do get DOMContentLoaded, so we'll wait for that. + let dclPromise = SpecialPowers.spawn(browser, [], async function () { + await ContentTaskUtils.waitForEvent(this, "DOMContentLoaded", false); + }); + BrowserTestUtils.loadURIString(browser, url); + await dclPromise; + + let menu = document.getElementById("menu_HelpPopup"); + ok(menu, "Help menu should exist"); + + let reportMenu = document.getElementById( + "menu_HelpPopup_reportPhishingtoolmenu" + ); + ok(reportMenu, "Report phishing menu item should exist"); + + let errorMenu = document.getElementById( + "menu_HelpPopup_reportPhishingErrortoolmenu" + ); + ok(errorMenu, "Report phishing error menu item should exist"); + + let menuOpen = BrowserTestUtils.waitForEvent(menu, "popupshown"); + menu.openPopup(null, "", 0, 0, false, null); + await menuOpen; + + testFn(reportMenu, errorMenu); + + let menuClose = BrowserTestUtils.waitForEvent(menu, "popuphidden"); + menu.hidePopup(); + await menuClose; + } + ); +} + +/** + * Tests that we show the "Report this page" menu item at a normal + * page. + */ +add_task(async function () { + await check_menu_at_page(NORMAL_PAGE, (reportMenu, errorMenu) => { + ok( + !reportMenu.hidden, + "Report phishing menu should be visible on normal sites" + ); + ok( + errorMenu.hidden, + "Report error menu item should be hidden on normal sites" + ); + }); +}); + +/** + * Tests that we show the "Report this page is okay" menu item at + * a reported attack site. + */ +add_task(async function () { + await check_menu_at_page(PHISH_PAGE, (reportMenu, errorMenu) => { + ok( + reportMenu.hidden, + "Report phishing menu should be hidden on phishing sites" + ); + ok( + !errorMenu.hidden, + "Report error menu item should be visible on phishing sites" + ); + }); +}); diff --git a/browser/components/safebrowsing/content/test/browser_mixedcontent_aboutblocked.js b/browser/components/safebrowsing/content/test/browser_mixedcontent_aboutblocked.js new file mode 100644 index 0000000000..7ee4a8a89d --- /dev/null +++ b/browser/components/safebrowsing/content/test/browser_mixedcontent_aboutblocked.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +const SECURE_CONTAINER_URL = + "https://example.com/browser/browser/components/safebrowsing/content/test/empty_file.html"; + +add_task(async function testNormalBrowsing() { + await BrowserTestUtils.withNewTab( + SECURE_CONTAINER_URL, + async function (browser) { + // Before we load the phish url, we have to make sure the hard-coded + // black list has been added to the database. + await new Promise(resolve => waitForDBInit(resolve)); + + let promise = new Promise(resolve => { + // Register listener before loading phish URL. + let removeFunc = BrowserTestUtils.addContentEventListener( + browser, + "AboutBlockedLoaded", + () => { + removeFunc(); + resolve(); + }, + { wantUntrusted: true } + ); + }); + + await SpecialPowers.spawn( + browser, + [PHISH_URL], + async function (aPhishUrl) { + // Create an iframe which is going to load a phish url. + let iframe = content.document.createElement("iframe"); + iframe.src = aPhishUrl; + content.document.body.appendChild(iframe); + } + ); + + await promise; + ok(true, "about:blocked is successfully loaded!"); + } + ); +}); diff --git a/browser/components/safebrowsing/content/test/browser_whitelisted.js b/browser/components/safebrowsing/content/test/browser_whitelisted.js new file mode 100644 index 0000000000..92c42a5b52 --- /dev/null +++ b/browser/components/safebrowsing/content/test/browser_whitelisted.js @@ -0,0 +1,46 @@ +/* Ensure that hostnames in the whitelisted pref are not blocked. */ + +const PREF_WHITELISTED_HOSTNAMES = "urlclassifier.skipHostnames"; +const TEST_PAGE = "http://www.itisatrap.org/firefox/its-an-attack.html"; +var tabbrowser = null; + +registerCleanupFunction(function () { + tabbrowser = null; + Services.prefs.clearUserPref(PREF_WHITELISTED_HOSTNAMES); + while (gBrowser.tabs.length > 1) { + gBrowser.removeCurrentTab(); + } +}); + +function testBlockedPage(window) { + info("Non-whitelisted pages must be blocked"); + ok(true, "about:blocked was shown"); +} + +function testWhitelistedPage(window) { + info("Whitelisted pages must be skipped"); + var getmeout_button = window.document.getElementById("getMeOutButton"); + var ignorewarning_button = window.document.getElementById( + "ignoreWarningButton" + ); + ok(!getmeout_button, "GetMeOut button not present"); + ok(!ignorewarning_button, "IgnoreWarning button not present"); +} + +add_task(async function testNormalBrowsing() { + tabbrowser = gBrowser; + let tab = (tabbrowser.selectedTab = BrowserTestUtils.addTab(tabbrowser)); + + info("Load a test page that's whitelisted"); + Services.prefs.setCharPref( + PREF_WHITELISTED_HOSTNAMES, + "example.com,www.ItIsaTrap.org,example.net" + ); + await promiseTabLoadEvent(tab, TEST_PAGE, "load"); + testWhitelistedPage(tab.ownerGlobal); + + info("Load a test page that's no longer whitelisted"); + Services.prefs.setCharPref(PREF_WHITELISTED_HOSTNAMES, ""); + await promiseTabLoadEvent(tab, TEST_PAGE, "AboutBlockedLoaded"); + testBlockedPage(tab.ownerGlobal); +}); diff --git a/browser/components/safebrowsing/content/test/empty_file.html b/browser/components/safebrowsing/content/test/empty_file.html new file mode 100644 index 0000000000..0dc101b533 --- /dev/null +++ b/browser/components/safebrowsing/content/test/empty_file.html @@ -0,0 +1 @@ +<html><body></body></html> diff --git a/browser/components/safebrowsing/content/test/head.js b/browser/components/safebrowsing/content/test/head.js new file mode 100644 index 0000000000..a68d1f317e --- /dev/null +++ b/browser/components/safebrowsing/content/test/head.js @@ -0,0 +1,103 @@ +// This url must sync with the table, url in SafeBrowsing.jsm addMozEntries +const PHISH_TABLE = "moztest-phish-simple"; +const PHISH_URL = "https://www.itisatrap.org/firefox/its-a-trap.html"; + +/** + * Waits for a load (or custom) event to finish in a given tab. If provided + * load an uri into the tab. + * + * @param tab + * The tab to load into. + * @param [optional] url + * The url to load, or the current url. + * @param [optional] event + * The load event type to wait for. Defaults to "load". + * @return {Promise} resolved when the event is handled. + * @resolves to the received event + * @rejects if a valid load event is not received within a meaningful interval + */ +function promiseTabLoadEvent(tab, url, eventType = "load") { + info(`Wait tab event: ${eventType}`); + + function handle(loadedUrl) { + if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) { + info(`Skipping spurious load event for ${loadedUrl}`); + return false; + } + + info("Tab event received: load"); + return true; + } + + let loaded; + if (eventType === "load") { + loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle); + } else { + // No need to use handle. + loaded = BrowserTestUtils.waitForContentEvent( + tab.linkedBrowser, + eventType, + true, + undefined, + true + ); + } + + if (url) { + BrowserTestUtils.loadURIString(tab.linkedBrowser, url); + } + + return loaded; +} + +// This function is mostly ported from classifierCommon.js +// under toolkit/components/url-classifier/tests/mochitest. +function waitForDBInit(callback) { + // Since there are two cases that may trigger the callback, + // we have to carefully avoid multiple callbacks and observer + // leaking. + let didCallback = false; + function callbackOnce() { + if (!didCallback) { + Services.obs.removeObserver(obsFunc, "mozentries-update-finished"); + callback(); + } + didCallback = true; + } + + // The first part: listen to internal event. + function obsFunc() { + ok(true, "Received internal event!"); + callbackOnce(); + } + Services.obs.addObserver(obsFunc, "mozentries-update-finished"); + + // The second part: we might have missed the event. Just do + // an internal database lookup to confirm if the url has been + // added. + let principal = Services.scriptSecurityManager.createContentPrincipal( + Services.io.newURI(PHISH_URL), + {} + ); + + let dbService = Cc["@mozilla.org/url-classifier/dbservice;1"].getService( + Ci.nsIUrlClassifierDBService + ); + dbService.lookup(principal, PHISH_TABLE, value => { + if (value === PHISH_TABLE) { + ok(true, "DB lookup success!"); + callbackOnce(); + } + }); +} + +Services.prefs.setCharPref( + "urlclassifier.malwareTable", + "moztest-malware-simple,moztest-unwanted-simple,moztest-harmful-simple" +); +Services.prefs.setCharPref("urlclassifier.phishTable", "moztest-phish-simple"); +Services.prefs.setCharPref( + "urlclassifier.blockedTable", + "moztest-block-simple" +); +SafeBrowsing.init(); |