Merge branch 'master' into custom

This commit is contained in:
Roy Tam 2019-03-02 12:23:02 +08:00
commit 3853dcca6a
13 changed files with 112 additions and 36 deletions

View file

@ -1438,3 +1438,11 @@ pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false);
// controlling validation are located in /services/sync/services-sync.js
pref("services.sync.validation.enabled", true);
#endif
// When a user cancels this number of authentication dialogs coming from
// a single web page (eTLD+1) in a row, all following authentication dialogs
// will be blocked (automatically canceled) for that page.
// This counter is per-tab and per-domain to minimize false positives.
// The counter resets when the page is reloaded from the UI
// (content-reloads do NOT clear this to mitigate reloading tricks).
pref("prompts.authentication_dialog_abuse_limit", 3);

View file

@ -3099,6 +3099,11 @@ function getWebNavigation()
}
function BrowserReloadWithFlags(reloadFlags) {
// Reset DOS mitigation for auth prompts when user initiates a reload.
let browser = gBrowser.selectedBrowser;
delete browser.authPromptCounter;
let url = gBrowser.currentURI.spec;
if (gBrowser.updateBrowserRemotenessByURL(gBrowser.selectedBrowser, url)) {
// If the remoteness has changed, the new browser doesn't have any

View file

@ -999,7 +999,8 @@
contentcontextmenu="contentAreaContextMenu"
autocompletepopup="PopupAutoComplete"
selectmenulist="ContentSelectDropdown"
datetimepicker="DateTimePickerPanel"/>
datetimepicker="DateTimePickerPanel"
authdosprotected="true" />
</vbox>
<vbox id="browser-border-end" hidden="true" layer="true"/>
</hbox>

View file

@ -25,7 +25,7 @@
<xul:vbox flex="1" class="browserContainer">
<xul:stack flex="1" class="browserStack" anonid="browserStack">
<xul:browser anonid="initialBrowser" type="content-primary" message="true" messagemanagergroup="browsers"
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectmenulist,datetimepicker"/>
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,selectmenulist,datetimepicker,authdosprotected"/>
</xul:stack>
</xul:vbox>
</xul:hbox>
@ -1952,6 +1952,10 @@
if (this.hasAttribute("datetimepicker")) {
b.setAttribute("datetimepicker", this.getAttribute("datetimepicker"));
}
if (this.hasAttribute("authdosprotected")) {
b.setAttribute("authdosprotected", this.getAttribute("authdosprotected"));
}
b.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
@ -3007,7 +3011,10 @@
<parameter name="aTab"/>
<body>
<![CDATA[
this.getBrowserForTab(aTab).reload();
let browser = this.getBrowserForTab(aTab);
// Reset DOS mitigation for basic auth prompt
delete browser.authPromptCounter;
browser.reload();
]]>
</body>
</method>

View file

@ -554,6 +554,9 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
Cu.reportError(ex);
}
// Reset DOS mitigations for the basic auth prompt.
delete browser.authPromptCounter;
let params = {
postData,
allowThirdPartyFixup: true,

View file

@ -1160,6 +1160,14 @@ pref("toolkit.pageThumbs.minHeight", 180);
pref("ui.key.menuAccessKeyFocuses", true);
#endif
// When a user cancels this number of authentication dialogs coming from
// a single web page (eTLD+1) in a row, all following authentication dialogs
// will be blocked (automatically canceled) for that page.
// This counter is per-tab and per-domain to minimize false positives.
// The counter resets when the page is reloaded from the UI
// (content-reloads do NOT clear this to mitigate reloading tricks).
pref("prompts.authentication_dialog_abuse_limit", 3);
// ****************** s4e prefs ******************
pref("status4evar.addonbar.borderStyle", false);
pref("status4evar.addonbar.closeButton", false);

View file

@ -2661,6 +2661,11 @@ function getWebNavigation()
}
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
* that framesets are handled properly. If we're in a special
* window (such as view-source) that has no session history, fall

View file

@ -965,7 +965,8 @@
tabcontainer="tabbrowser-tabs"
contentcontextmenu="contentAreaContextMenu"
autocompletepopup="PopupAutoComplete"
datetimepicker="DateTimePickerPanel"/>
datetimepicker="DateTimePickerPanel"
authdosprotected="true"/>
<chatbar id="pinnedchats" layer="true" mousethrough="always" hidden="true"/>
<statuspanel id="statusbar-display" inactive="true"/>
</vbox>

View file

@ -30,7 +30,7 @@
<xul:vbox flex="1" class="browserContainer">
<xul:stack flex="1" class="browserStack" anonid="browserStack">
<xul:browser anonid="initialBrowser" type="content-primary" message="true" disablehistory="true"
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,datetimepicker"/>
xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup,datetimepicker,authdosprotected"/>
</xul:stack>
</xul:vbox>
</xul:hbox>
@ -1588,6 +1588,10 @@
if (this.hasAttribute("datetimepicker")) {
b.setAttribute("datetimepicker", this.getAttribute("datetimepicker"));
}
if (this.hasAttribute("authdosprotected")) {
b.setAttribute("authdosprotected", this.getAttribute("authdosprotected"));
}
// Create the browserStack container
var stack = document.createElementNS(NS_XUL, "stack");
@ -2458,7 +2462,10 @@
<parameter name="aTab"/>
<body>
<![CDATA[
this.getBrowserForTab(aTab).reload();
let browser = this.getBrowserForTab(aTab);
// Reset DOS mitigation for basic auth prompt
delete browser.authPromptCounter;
browser.reload();
]]>
</body>
</method>

View file

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

View file

@ -5459,8 +5459,9 @@ pref("dom.storageManager.enabled", true);
pref("dom.storageManager.enabled", false);
#endif
// When a user cancels this number of authentication dialogs coming from
// a single web page in a row, all following authentication dialogs will
// be blocked (automatically canceled) for that page. The counter resets
// when the page is reloaded. To turn this feature off, just set the limit to 0.
pref("prompts.authentication_dialog_abuse_limit", 3);
// DoS protection for HTTP Auth prompt spawning.
// -1 = completely disable HTTP Auth prompting. (careful!)
// 0 = disable this DoS protection
// >0 = suppress further prompts after the user has canceled the dialog n times
// See application preferences for appropriate defaults.
pref("prompts.authentication_dialog_abuse_limit", 0);

View file

@ -97,17 +97,25 @@ LoginManagerPromptFactory.prototype = {
return;
}
// Allow only a limited number of authentication dialogs when they are all
// canceled by the user.
var cancelationCounter = (prompter._browser && prompter._browser.canceledAuthenticationPromptCounter) || { count: 0, id: 0 };
if (prompt.channel) {
var httpChannel = prompt.channel.QueryInterface(Ci.nsIHttpChannel);
if (httpChannel) {
var windowId = httpChannel.topLevelContentWindowId;
if (windowId != cancelationCounter.id) {
// window has been reloaded or navigated, reset the counter
cancelationCounter = { count: 0, id: windowId };
}
// Set up a counter for ensuring that the basic auth prompt can not
// be abused for DOS-style attacks. With this counter, each eTLD+1
// per browser will get a limited number of times a user can
// cancel the prompt until we stop showing it.
let browser = prompter._browser;
let baseDomain = null;
if (browser && browser.isAuthDOSProtected) {
try {
baseDomain = Services.eTLD.getBaseDomainFromHost(hostname);
} 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;
self._asyncPromptInProgress = false;
if (ok) {
cancelationCounter.count = 0;
} else {
cancelationCounter.count++;
}
if (prompter._browser) {
prompter._browser.canceledAuthenticationPromptCounter = cancelationCounter;
if (browser && browser.isAuthDOSProtected) {
// Reset the counter state if the user replied to a prompt and actually
// tried to login (vs. simply clicking any button to get out).
if (ok && (prompt.authInfo.username || prompt.authInfo.password)) {
browser.authPromptCounter[baseDomain] = 0;
} else {
browser.authPromptCounter[baseDomain] += 1;
}
}
}
@ -168,14 +177,27 @@ LoginManagerPromptFactory.prototype = {
var cancelDialogLimit = Services.prefs.getIntPref("prompts.authentication_dialog_abuse_limit");
this.log("cancelationCounter =", cancelationCounter);
if (cancelDialogLimit && cancelationCounter.count >= cancelDialogLimit) {
this.log("Blocking auth dialog, due to exceeding dialog bloat limit");
delete this._asyncPrompts[hashKey];
// Block the auth prompt if:
// - There is an attached browser element
// - The browser element has opted-in to DOS protection
// - The dialog cancellation limit is not 0 (= feature disabled)
// - The amount of cancellations >= the set abuse limit
if (browser && browser.isAuthDOSProtected) {
let cancelationCounter = browser.authPromptCounter[baseDomain];
this.log("cancelationCounter =", cancelationCounter);
// just make the runnable cancel all consumers
runnable.cancel = true;
if (cancelDialogLimit && cancelationCounter >= cancelDialogLimit) {
this.log("Blocking auth dialog, due to exceeding dialog bloat limit");
delete this._asyncPrompts[hashKey];
// just make the runnable cancel all consumers
runnable.cancel = true;
} else {
this._asyncPromptInProgress = true;
prompt.inProgress = true;
}
} else {
// No DOS protection: prompt
this._asyncPromptInProgress = true;
prompt.inProgress = true;
}

View file

@ -899,6 +899,10 @@
<field name="mIconURL">null</field>
<property name="isAuthDOSProtected"
onget="return (this.getAttribute('authdosprotected') == 'true');"
readonly="true"/>
<!-- This is managed by the tabbrowser -->
<field name="lastURI">null</field>