diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/components/passwordmgr/test/browser/browser_basicAuth_rateLimit.js | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/browser/browser_basicAuth_rateLimit.js b/toolkit/components/passwordmgr/test/browser/browser_basicAuth_rateLimit.js new file mode 100644 index 0000000000..1c12a8fec5 --- /dev/null +++ b/toolkit/components/passwordmgr/test/browser/browser_basicAuth_rateLimit.js @@ -0,0 +1,146 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This tests that the basic auth dialog can not be used for DOS attacks +// and that the protections are reset on user-initiated navigation/reload. + +let promptModalType = Services.prefs.getIntPref("prompts.modalType.httpAuth"); + +function promiseAuthWindowShown() { + return PromptTestUtils.handleNextPrompt( + window, + { modalType: promptModalType, promptType: "promptUserAndPass" }, + { buttonNumClick: 1 } + ); +} + +add_task(async function test() { + await BrowserTestUtils.withNewTab( + "https://example.com", + async function (browser) { + let cancelDialogLimit = Services.prefs.getIntPref( + "prompts.authentication_dialog_abuse_limit" + ); + + let authShown = promiseAuthWindowShown(); + let browserLoaded = BrowserTestUtils.browserLoaded(browser); + BrowserTestUtils.startLoadingURIString( + browser, + "https://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs" + ); + await authShown; + Assert.ok(true, "Seen dialog number 1"); + await browserLoaded; + Assert.ok(true, "Loaded document number 1"); + + // Reload the document a bit more often than should be allowed. + // As long as we're in the acceptable range we should receive + // auth prompts, otherwise we should not receive them and the + // page should just load. + // We've already seen the dialog once, hence we start the loop at 1. + for (let i = 1; i < cancelDialogLimit + 2; i++) { + if (i < cancelDialogLimit) { + authShown = promiseAuthWindowShown(); + } + browserLoaded = BrowserTestUtils.browserLoaded(browser); + SpecialPowers.spawn(browser, [], function () { + content.document.location.reload(); + }); + if (i < cancelDialogLimit) { + await authShown; + Assert.ok(true, `Seen dialog number ${i + 1}`); + } + await browserLoaded; + Assert.ok(true, `Loaded document number ${i + 1}`); + } + + let reloadButton = document.getElementById("reload-button"); + await TestUtils.waitForCondition( + () => !reloadButton.hasAttribute("disabled") + ); + + // Verify that we can click the reload button to reset the counter. + authShown = promiseAuthWindowShown(); + browserLoaded = BrowserTestUtils.browserLoaded(browser); + reloadButton.click(); + await authShown; + Assert.ok(true, "Seen dialog number 1"); + await browserLoaded; + Assert.ok(true, "Loaded document number 1"); + + // Now check loading subresources with auth on the page. + browserLoaded = BrowserTestUtils.browserLoaded(browser); + BrowserTestUtils.startLoadingURIString(browser, "https://example.com"); + await browserLoaded; + + // We've already seen the dialog once, hence we start the loop at 1. + for (let i = 1; i < cancelDialogLimit + 2; i++) { + if (i < cancelDialogLimit) { + authShown = promiseAuthWindowShown(); + } + + let iframeLoaded = SpecialPowers.spawn(browser, [], async function () { + let doc = content.document; + let iframe = doc.createElement("iframe"); + doc.body.appendChild(iframe); + let loaded = new Promise(resolve => { + iframe.addEventListener( + "load", + function (e) { + resolve(); + }, + { once: true } + ); + }); + iframe.src = + "https://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs"; + await loaded; + }); + + if (i < cancelDialogLimit) { + await authShown; + Assert.ok(true, `Seen dialog number ${i + 1}`); + } + + await iframeLoaded; + Assert.ok(true, `Loaded iframe number ${i + 1}`); + } + + // Verify that third party subresources can not spawn new auth dialogs. + let iframeLoaded = SpecialPowers.spawn(browser, [], async function () { + let doc = content.document; + let iframe = doc.createElement("iframe"); + doc.body.appendChild(iframe); + let loaded = new Promise(resolve => { + iframe.addEventListener( + "load", + function (e) { + resolve(); + }, + { once: true } + ); + }); + iframe.src = + "https://example.org/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs"; + await loaded; + }); + + await iframeLoaded; + Assert.ok( + true, + "Loaded a third party iframe without showing the auth dialog" + ); + + // Verify that pressing enter in the urlbar also resets the counter. + authShown = promiseAuthWindowShown(); + browserLoaded = BrowserTestUtils.browserLoaded(browser); + gURLBar.value = + "https://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs"; + gURLBar.focus(); + EventUtils.synthesizeKey("KEY_Enter"); + await authShown; + await browserLoaded; + } + ); +}); |