Bug 1579285 - Offer to enable TLS 1.0 on neterror page r=johannh

As we roll out the TLS 1.0 and 1.1 deprecation, sites that don't support TLS 1.2
will show the neterror page.  This adds a box to that page that shows in this
specific case.  That box explains what is going on and gives an option to
re-enable TLS 1.0.

As mentioned, this will show alongside an option to reset TLS-related
preferences if any overrides are active.

Hitting the button will set the new pref to 'true' and reload the page.

Once the override is engaged, the option won't show, but that option to reset
preferences will show (as this is a TLS-related preference).

The intent is to remove this affordance in March 2020 as we formally move to
having TLS 1.2 the minimum version.  All going to plan, this will only affect
prerelease channels, though anyone who has tweaked security.tls.version.* could
also see this.

Differential Revision: https://phabricator.services.mozilla.com/D45799

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Martin Thomson 2019-09-27 00:18:11 +00:00
Родитель bcf590a1d0
Коммит cd23d1b0d9
7 изменённых файлов: 203 добавлений и 52 удалений

Просмотреть файл

@ -74,6 +74,18 @@ function showPrefChangeContainer() {
addAutofocus("#prefResetButton", "beforeend"); addAutofocus("#prefResetButton", "beforeend");
} }
function showTls10Container() {
const panel = document.getElementById("enableTls10Container");
panel.style.display = "block";
document.getElementById("netErrorButtonContainer").style.display = "none";
const button = document.getElementById("enableTls10Button");
button.addEventListener("click", function enableTls10(e) {
RPMSetBoolPref("security.tls.version.enable-deprecated", true);
retryThis(button);
});
addAutofocus("#enableTls10Button", "beforeend");
}
function setupAdvancedButton() { function setupAdvancedButton() {
// Get the hostname and add it to the panel // Get the hostname and add it to the panel
var panel = document.getElementById("badCertAdvancedPanel"); var panel = document.getElementById("badCertAdvancedPanel");
@ -264,26 +276,36 @@ function initPage() {
if (err == "nssFailure2") { if (err == "nssFailure2") {
setupErrorUI(); setupErrorUI();
RPMAddMessageListener("HasChangedCertPrefs", msg => { const errorCode = document.getNetErrorInfo().errorCodeString;
let hasChangedCertPrefs = msg.data.hasChangedCertPrefs; const isTlsVersionError = (errorCode == "SSL_ERROR_UNSUPPORTED_VERSION");
const tls10OverrideEnabled = RPMGetBoolPref(
"security.tls.version.enable-deprecated"
);
let errorCode = document.getNetErrorInfo().errorCodeString; if (isTlsVersionError && !tls10OverrideEnabled) {
let hasPrefStyleError = [ // This is probably a TLS 1.0 server; offer to re-enable.
showTls10Container();
} else {
const hasPrefStyleError = [
"interrupted", // This happens with subresources that are above the max tls "interrupted", // This happens with subresources that are above the max tls
"SSL_ERROR_PROTOCOL_VERSION_ALERT",
"SSL_ERROR_UNSUPPORTED_VERSION",
"SSL_ERROR_NO_CYPHER_OVERLAP",
"SSL_ERROR_NO_CIPHERS_SUPPORTED", "SSL_ERROR_NO_CIPHERS_SUPPORTED",
"SSL_ERROR_NO_CYPHER_OVERLAP",
"SSL_ERROR_PROTOCOL_VERSION_ALERT",
"SSL_ERROR_UNSUPPORTED_VERSION"
].some(substring => { ].some(substring => {
return substring == errorCode; return substring == errorCode;
}); });
// If it looks like an error that is user config based if (hasPrefStyleError) {
if (hasPrefStyleError && hasChangedCertPrefs) { RPMAddMessageListener("HasChangedCertPrefs", msg => {
showPrefChangeContainer(); if (msg.data.hasChangedCertPrefs) {
// Configuration overrides might have caused this; offer to reset.
showPrefChangeContainer();
}
});
RPMSendAsyncMessage("GetChangedCertPrefs");
} }
}); }
RPMSendAsyncMessage("GetChangedCertPrefs");
} }
if (err == "sslv3Used") { if (err == "sslv3Used") {

Просмотреть файл

@ -181,6 +181,14 @@
</div> </div>
</div> </div>
<!-- UI to temporarily re-enable TLS 1.0 and 1.1.
This should be removed after March 2020, see bug 1579285. -->
<div id="enableTls10Container" class="button-container">
<p>&enableTls10.longDesc;</p>
<p>&enableTls10.note;</p>
<button id="enableTls10Button" class="primary">&enableTls10.label;</button>
</div>
<!-- UI for option to report certificate errors to Mozilla. Removed on <!-- UI for option to report certificate errors to Mozilla. Removed on
init for other error types .--> init for other error types .-->
<div id="prefChangeContainer" class="button-container"> <div id="prefChangeContainer" class="button-container">

Просмотреть файл

@ -3,23 +3,25 @@
"use strict"; "use strict";
const LOW_TLS_VERSION = "https://tls1.example.com/"; const SSL3_PAGE = "https://ssl3.example.com/";
const TLS10_PAGE = "https://tls1.example.com/";
const TLS12_PAGE = "https://tls12.example.com/";
add_task(async function checkReturnToPreviousPage() { add_task(async function resetToDefaultConfig() {
info( info(
"Loading a TLS page that isn't supported, ensure we have a fix button and clicking it then loads the page" "Change TLS config to cause page load to fail, check that reset button is shown and that it works"
); );
// Set ourselves up for TLS error // Set ourselves up for TLS error
Services.prefs.setIntPref("security.tls.version.max", 3); Services.prefs.setIntPref("security.tls.version.min", 1); // TLS 1.0
Services.prefs.setIntPref("security.tls.version.min", 3); Services.prefs.setIntPref("security.tls.version.max", 1);
let browser; let browser;
let pageLoaded; let pageLoaded;
await BrowserTestUtils.openNewForegroundTab( await BrowserTestUtils.openNewForegroundTab(
gBrowser, gBrowser,
() => { () => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, LOW_TLS_VERSION); gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TLS12_PAGE);
browser = gBrowser.selectedBrowser; browser = gBrowser.selectedBrowser;
pageLoaded = BrowserTestUtils.waitForErrorPage(browser); pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
}, },
@ -29,59 +31,54 @@ add_task(async function checkReturnToPreviousPage() {
info("Loading and waiting for the net error"); info("Loading and waiting for the net error");
await pageLoaded; await pageLoaded;
// NB: This code assumes that the error page and the test page load in the // Setup an observer for the target page.
// same process. If this test starts to fail, it could be because they load const finalLoadComplete = BrowserTestUtils.browserLoaded(
// in different processes. browser,
await ContentTask.spawn(browser, LOW_TLS_VERSION, async function( false,
LOW_TLS_VERSION_ TLS12_PAGE
) { );
ok(
content.document.getElementById("prefResetButton").getBoundingClientRect()
.left >= 0,
"Should have a visible button"
);
await ContentTask.spawn(browser, null, async function() {
const doc = content.document;
ok( ok(
content.document.documentURI.startsWith("about:neterror"), doc.documentURI.startsWith("about:neterror"),
"Should be showing error page" "Should be showing error page"
); );
let doc = content.document; const prefResetButton = doc.getElementById("prefResetButton");
let prefResetButton = doc.getElementById("prefResetButton"); ok(
ContentTaskUtils.is_visible(prefResetButton),
"prefResetButton should be visible"
);
is( is(
prefResetButton.getAttribute("autofocus"), prefResetButton.getAttribute("autofocus"),
"true", "true",
"prefResetButton has autofocus" "prefResetButton has autofocus"
); );
prefResetButton.click(); prefResetButton.click();
await ContentTaskUtils.waitForEvent(this, "pageshow", true);
is(
content.document.documentURI,
LOW_TLS_VERSION_,
"Should not be showing page"
);
}); });
info("Waiting for the TLS 1.2 page to load after the click");
await finalLoadComplete;
Services.prefs.clearUserPref("security.tls.version.min");
Services.prefs.clearUserPref("security.tls.version.max");
BrowserTestUtils.removeTab(gBrowser.selectedTab); BrowserTestUtils.removeTab(gBrowser.selectedTab);
}); });
add_task(async function checkLearnMoreLink() { add_task(async function checkLearnMoreLink() {
info( info("Load an unsupported TLS page and check for a learn more link");
"Loading a TLS page that isn't supported and checking the learn more link"
);
// Set ourselves up for TLS error // Set ourselves up for TLS error
Services.prefs.setIntPref("security.tls.version.max", 3);
Services.prefs.setIntPref("security.tls.version.min", 3); Services.prefs.setIntPref("security.tls.version.min", 3);
Services.prefs.setIntPref("security.tls.version.max", 4);
let browser; let browser;
let pageLoaded; let pageLoaded;
await BrowserTestUtils.openNewForegroundTab( await BrowserTestUtils.openNewForegroundTab(
gBrowser, gBrowser,
() => { () => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, LOW_TLS_VERSION); gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TLS10_PAGE);
browser = gBrowser.selectedBrowser; browser = gBrowser.selectedBrowser;
pageLoaded = BrowserTestUtils.waitForErrorPage(browser); pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
}, },
@ -91,16 +88,16 @@ add_task(async function checkLearnMoreLink() {
info("Loading and waiting for the net error"); info("Loading and waiting for the net error");
await pageLoaded; await pageLoaded;
let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL"); const baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
await ContentTask.spawn(browser, baseURL, function(_baseURL) { await ContentTask.spawn(browser, baseURL, function(_baseURL) {
const doc = content.document;
ok( ok(
content.document.documentURI.startsWith("about:neterror"), doc.documentURI.startsWith("about:neterror"),
"Should be showing error page" "Should be showing error page"
); );
let doc = content.document; const learnMoreLink = doc.getElementById("learnMoreLink");
let learnMoreLink = doc.getElementById("learnMoreLink");
ok( ok(
ContentTaskUtils.is_visible(learnMoreLink), ContentTaskUtils.is_visible(learnMoreLink),
"Learn More link is visible" "Learn More link is visible"
@ -108,7 +105,120 @@ add_task(async function checkLearnMoreLink() {
is(learnMoreLink.getAttribute("href"), _baseURL + "connection-not-secure"); is(learnMoreLink.getAttribute("href"), _baseURL + "connection-not-secure");
}); });
Services.prefs.clearUserPref("security.tls.version.max");
Services.prefs.clearUserPref("security.tls.version.min"); Services.prefs.clearUserPref("security.tls.version.min");
Services.prefs.clearUserPref("security.tls.version.max");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function checkEnable10() {
info(
"Load a page with a deprecated TLS version, an option to enable TLS 1.0 is offered and it works"
);
Services.prefs.setIntPref("security.tls.version.min", 3);
// Disable TLS 1.3 so that we trigger a SSL_ERROR_UNSUPPORTED_VERSION.
// As NSS generates an alert rather than negotiating a lower version
// if we use the supported_versions extension from TLS 1.3.
Services.prefs.setIntPref("security.tls.version.max", 3);
let browser;
let pageLoaded;
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
() => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, TLS10_PAGE);
browser = gBrowser.selectedBrowser;
pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
},
false
);
info("Loading and waiting for the net error");
await pageLoaded;
// Setup an observer for the target page.
const finalLoadComplete = BrowserTestUtils.browserLoaded(
browser,
false,
TLS10_PAGE
);
await ContentTask.spawn(browser, null, async function() {
const doc = content.document;
ok(
doc.documentURI.startsWith("about:neterror"),
"Should be showing error page"
);
const enableTls10Button = doc.getElementById("enableTls10Button");
ok(
ContentTaskUtils.is_visible(enableTls10Button),
"Option to re-enable TLS 1.0 is visible"
);
enableTls10Button.click();
// It should not also offer to reset preferences instead.
const prefResetButton = doc.getElementById("prefResetButton");
ok(
!ContentTaskUtils.is_visible(prefResetButton),
"prefResetButton should NOT be visible"
);
});
info("Waiting for the TLS 1.0 page to load after the click");
await finalLoadComplete;
Services.prefs.clearUserPref("security.tls.version.min");
Services.prefs.clearUserPref("security.tls.version.max");
Services.prefs.clearUserPref("security.tls.version.enable-deprecated");
BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
add_task(async function dontOffer10WhenAlreadyEnabled() {
info("An option to enable TLS 1.0 is not offered if already enabled");
Services.prefs.setIntPref("security.tls.version.min", 3);
Services.prefs.setIntPref("security.tls.version.max", 3);
Services.prefs.setBoolPref("security.tls.version.enable-deprecated", true);
let browser;
let pageLoaded;
await BrowserTestUtils.openNewForegroundTab(
gBrowser,
() => {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, SSL3_PAGE);
browser = gBrowser.selectedBrowser;
pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
},
false
);
info("Loading and waiting for the net error");
await pageLoaded;
await ContentTask.spawn(browser, null, async function() {
const doc = content.document;
ok(
doc.documentURI.startsWith("about:neterror"),
"Should be showing error page"
);
const enableTls10Button = doc.getElementById("enableTls10Button");
ok(
!ContentTaskUtils.is_visible(enableTls10Button),
"Option to re-enable TLS 1.0 is not visible"
);
// It should offer to reset preferences instead.
const prefResetButton = doc.getElementById("prefResetButton");
ok(
ContentTaskUtils.is_visible(prefResetButton),
"prefResetButton should be visible"
);
});
Services.prefs.clearUserPref("security.tls.version.min");
Services.prefs.clearUserPref("security.tls.version.max");
Services.prefs.clearUserPref("security.tls.version.enable-deprecated");
BrowserTestUtils.removeTab(gBrowser.selectedTab); BrowserTestUtils.removeTab(gBrowser.selectedTab);
}); });

Просмотреть файл

@ -230,5 +230,9 @@ was trying to connect. -->
<!ENTITY prefReset.longDesc "It looks like your network security settings might be causing this. Do you want the default settings to be restored?"> <!ENTITY prefReset.longDesc "It looks like your network security settings might be causing this. Do you want the default settings to be restored?">
<!ENTITY prefReset.label "Restore default settings"> <!ENTITY prefReset.label "Restore default settings">
<!ENTITY enableTls10.longDesc "This website might not support the TLS 1.2 protocol, which is the minimum version supported by &brandShortName;. Enabling TLS 1.0 and TLS 1.1 might allow this connection to succeed.">
<!ENTITY enableTls10.note "TLS 1.0 and TLS 1.1 will be permanently disabled in a future release.">
<!ENTITY enableTls10.label "Enable TLS 1.0 and 1.1">
<!ENTITY networkProtocolError.title "Network Protocol Error"> <!ENTITY networkProtocolError.title "Network Protocol Error">
<!ENTITY networkProtocolError.longDesc "<p>The page you are trying to view cannot be shown because an error in the network protocol was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>"> <!ENTITY networkProtocolError.longDesc "<p>The page you are trying to view cannot be shown because an error in the network protocol was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">

Просмотреть файл

@ -47,6 +47,10 @@ button:disabled {
margin-top: 2em; margin-top: 2em;
} }
#enableTls10Container {
display: none;
}
#prefChangeContainer { #prefChangeContainer {
display: none; display: none;
} }

Просмотреть файл

@ -56,9 +56,10 @@ let RPMAccessManager = {
"about:neterror": { "about:neterror": {
getFormatURLPref: ["app.support.baseURL"], getFormatURLPref: ["app.support.baseURL"],
getBoolPref: [ getBoolPref: [
"security.ssl.errorReporting.enabled",
"security.ssl.errorReporting.automatic",
"security.certerror.hideAddException", "security.certerror.hideAddException",
"security.ssl.errorReporting.automatic",
"security.ssl.errorReporting.enabled",
"security.tls.version.enable-deprecated",
], ],
}, },
"about:privatebrowsing": { "about:privatebrowsing": {

Просмотреть файл

@ -26,6 +26,8 @@ const kAllowedPrefs = new Set([
"reader.color_scheme", "reader.color_scheme",
"reader.content_width", "reader.content_width",
"reader.line_height", "reader.line_height",
"security.tls.version.enable-deprecated",
]); ]);
const kPrefTypeMap = new Map([ const kPrefTypeMap = new Map([