WIP fix 1

This commit is contained in:
wolfbeast 2019-02-28 10:02:19 +01:00 • committed by Roy Tam
commit 54df9f8a30
4 changed files with 42 additions and 20 deletions

View file

@ -2661,6 +2661,11 @@ function getWebNavigation()
} }
function BrowserReloadWithFlags(reloadFlags) { function BrowserReloadWithFlags(reloadFlags) {
// Reset DOS mitigation for auth prompts when user initiates a reload.
let browser = gBrowser.selectedBrowser;
delete browser.authPromptCounter;
/* First, we'll try to use the session history object to reload so /* First, we'll try to use the session history object to reload so
* that framesets are handled properly. If we're in a special * that framesets are handled properly. If we're in a special
* window (such as view-source) that has no session history, fall * window (such as view-source) that has no session history, fall

View file

@ -2458,7 +2458,10 @@
<parameter name="aTab"/> <parameter name="aTab"/>
<body> <body>
<![CDATA[ <![CDATA[
this.getBrowserForTab(aTab).reload(); let browser = this.getBrowserForTab(aTab);
// Reset DOS mitigation for basic auth prompt
delete browser.authPromptCounter;
browser.reload();
]]> ]]>
</body> </body>
</method> </method>

View file

@ -302,6 +302,10 @@
// but don't let that interfere with the loading of the url. // but don't let that interfere with the loading of the url.
Cu.reportError(ex); Cu.reportError(ex);
} }
// Reset DOS mitigations for the basic auth prompt.
let browser = gBrowser.selectedBrowser;
delete browser.authPromptCounter;
function loadCurrent() { function loadCurrent() {
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;

View file

@ -97,17 +97,25 @@ LoginManagerPromptFactory.prototype = {
return; return;
} }
// Allow only a limited number of authentication dialogs when they are all // Set up a counter for ensuring that the basic auth prompt can not
// canceled by the user. // be abused for DOS-style attacks. With this counter, each eTLD+1
var cancelationCounter = (prompter._browser && prompter._browser.canceledAuthenticationPromptCounter) || { count: 0, id: 0 }; // per browser will get a limited number of times a user can
if (prompt.channel) { // cancel the prompt until we stop showing it.
var httpChannel = prompt.channel.QueryInterface(Ci.nsIHttpChannel); let browser = prompter._browser;
if (httpChannel) { let baseDomain = null;
var windowId = httpChannel.topLevelContentWindowId; if (browser) {
if (windowId != cancelationCounter.id) { try {
// window has been reloaded or navigated, reset the counter baseDomain = Services.eTLD.getBaseDomainFromHost(hostname);
cancelationCounter = { count: 0, id: windowId }; } catch (e) {
} baseDomain = hostname;
}
if (!browser.authPromptCounter) {
browser.authPromptCounter = {};
}
if (!browser.authPromptCounter[baseDomain]) {
browser.authPromptCounter[baseDomain] = 0;
} }
} }
@ -137,13 +145,14 @@ LoginManagerPromptFactory.prototype = {
prompt.inProgress = false; prompt.inProgress = false;
self._asyncPromptInProgress = false; self._asyncPromptInProgress = false;
if (ok) { if (browser) {
cancelationCounter.count = 0; // Reset the counter state if the user replied to a prompt and actually
} else { // tried to login (vs. simply clicking any button to get out).
cancelationCounter.count++; if (ok && (prompt.authInfo.username || prompt.authInfo.password)) {
} browser.authPromptCounter[baseDomain] = 0;
if (prompter._browser) { } else {
prompter._browser.canceledAuthenticationPromptCounter = cancelationCounter; browser.authPromptCounter[baseDomain] += 1;
}
} }
} }
@ -168,8 +177,9 @@ LoginManagerPromptFactory.prototype = {
var cancelDialogLimit = Services.prefs.getIntPref("prompts.authentication_dialog_abuse_limit"); var cancelDialogLimit = Services.prefs.getIntPref("prompts.authentication_dialog_abuse_limit");
let cancelationCounter = browser.authPromptCounter[baseDomain];
this.log("cancelationCounter =", cancelationCounter); this.log("cancelationCounter =", cancelationCounter);
if (cancelDialogLimit && cancelationCounter.count >= cancelDialogLimit) { if (cancelDialogLimit && cancelationCounter >= cancelDialogLimit) {
this.log("Blocking auth dialog, due to exceeding dialog bloat limit"); this.log("Blocking auth dialog, due to exceeding dialog bloat limit");
delete this._asyncPrompts[hashKey]; delete this._asyncPrompts[hashKey];