Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* 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.
function promiseAuthWindowShown() {
return PromptTestUtils.handleNextPrompt(
window,
{ modalType: Ci.nsIPrompt.MODAL_TYPE_TAB, promptType: "promptUserAndPass" },
{ buttonNumClick: 1 }
);
}
add_task(async function test() {
await BrowserTestUtils.withNewTab(
async function (browser) {
let cancelDialogLimit = Services.prefs.getIntPref(
"prompts.authentication_dialog_abuse_limit"
);
let authShown = promiseAuthWindowShown();
let browserLoaded = BrowserTestUtils.browserLoaded(browser);
BrowserTestUtils.startLoadingURIString(
browser,
);
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", _e => resolve(), { once: true });
});
iframe.src =
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", () => resolve(), { once: true });
});
iframe.src =
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 =
gURLBar.focus();
EventUtils.synthesizeKey("KEY_Enter");
await authShown;
await browserLoaded;
}
);
});