зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1806412 - Add a custom about:neterror page for the DNS native fallback warning r=necko-reviewers,fluent-reviewers,flod,valentin,pbz
Similar to Bug1596845
- Implement new error page for DNS errors when DoH is enabled - this changes about:neterror to show an error page specific to DNS failures that would have previously been resolved by fallback to native resolution. With the preference, network.trr.display_fallback_warning set (defaults to off), DNS resolution will now fail when the user is in trr mode 2 (trr first) and either of these occur: - the TRR cannot be confirmed - the canary network heuristic is tripped The new custom error page will be shown for failures resulting from these conditions. This offers the user more information about the failure, and the option to bypass this warning going forward. As with Bug1596845
, this is experimental and will be further improved over time. To see the error page, the user must first set the network.trr.display_fallback_warning preference. They must then encounter one of the conditions (unable to confirm TRR or tripping the canary heuristic). Preventing TRR confirmation can be done by modifying their local hosts file to map their regional TRR domain's to an invalid address. Project plan: https://docs.google.com/document/d/12IGABt1eXI276qHduXXbVZqRFrhLN7Ad3gKEgxz81sE Copy deck: https://docs.google.com/document/d/130UTox8bQbybjYIwvltR4qBg2hWjsGhuNUHypLwUAEQ Depends on D165557 Differential Revision: https://phabricator.services.mozilla.com/D165558
This commit is contained in:
Родитель
a2df091c3f
Коммит
902da73f87
|
@ -29,7 +29,8 @@ class NetErrorChild extends RemotePageChild {
|
|||
"RPMCheckAlternateHostAvailable",
|
||||
"RPMGetHttpResponseHeader",
|
||||
"RPMIsTRROnlyFailure",
|
||||
"RPMShowTRROnlyFailureError",
|
||||
"RPMIsFirefox",
|
||||
"RPMIsNativeFallbackFailure",
|
||||
"RPMOpenPreferences",
|
||||
"RPMGetTRRSkipReason",
|
||||
"RPMGetTRRDomain",
|
||||
|
@ -162,7 +163,7 @@ class NetErrorChild extends RemotePageChild {
|
|||
}
|
||||
|
||||
RPMIsTRROnlyFailure() {
|
||||
// As per RPMShowTRROnlyFailureError, we will only show this in Firefox
|
||||
// We will only show this in Firefox because the options may direct users to settings only available on Firefox Desktop
|
||||
let channel = this.contentWindow?.docShell?.failedChannel?.QueryInterface(
|
||||
Ci.nsIHttpChannelInternal
|
||||
);
|
||||
|
@ -172,10 +173,37 @@ class NetErrorChild extends RemotePageChild {
|
|||
return channel.effectiveTRRMode == Ci.nsIRequest.TRR_ONLY_MODE;
|
||||
}
|
||||
|
||||
RPMShowTRROnlyFailureError() {
|
||||
RPMIsFirefox() {
|
||||
return lazy.AppInfo.isFirefox;
|
||||
}
|
||||
|
||||
RPMIsNativeFallbackFailure() {
|
||||
let channel = this.contentWindow?.docShell?.failedChannel?.QueryInterface(
|
||||
Ci.nsIHttpChannelInternal
|
||||
);
|
||||
let value = channel?.trrSkipReason ?? Ci.nsITRRSkipReason.TRR_UNSET;
|
||||
|
||||
const warningReasons = new Set([
|
||||
Ci.nsITRRSkipReason.TRR_NOT_CONFIRMED,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_GOOGLE_SAFESEARCH,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_YOUTUBE_SAFESEARCH,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_ZSCALER_CANARY,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_CANARY,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_MODIFIED_ROOTS,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_PARENTAL_CONTROLS,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_THIRD_PARTY_ROOTS,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_ENTERPRISE_POLICY,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_VPN,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_PROXY,
|
||||
Ci.nsITRRSkipReason.TRR_HEURISTIC_TRIPPED_NRPT,
|
||||
]);
|
||||
|
||||
return (
|
||||
Services.dns.currentTrrMode == Ci.nsIRequest.TRR_FIRST_MODE &&
|
||||
warningReasons.has(value)
|
||||
);
|
||||
}
|
||||
|
||||
RPMGetTRRSkipReason() {
|
||||
let channel = this.contentWindow?.docShell?.failedChannel?.QueryInterface(
|
||||
Ci.nsIHttpChannelInternal
|
||||
|
|
|
@ -239,6 +239,12 @@ function initPage() {
|
|||
|
||||
const isTRROnlyFailure = gErrorCode == "dnsNotFound" && RPMIsTRROnlyFailure();
|
||||
|
||||
let isNativeFallbackWarning = false;
|
||||
if (RPMGetBoolPref("network.trr.display_fallback_warning")) {
|
||||
isNativeFallbackWarning =
|
||||
gErrorCode == "dnsNotFound" && RPMIsNativeFallbackFailure();
|
||||
}
|
||||
|
||||
const docTitle = document.querySelector("title");
|
||||
const bodyTitle = document.querySelector(".title-text");
|
||||
const shortDesc = document.getElementById("errorShortDesc");
|
||||
|
@ -390,90 +396,99 @@ function initPage() {
|
|||
bodyTitleId = "generic-title";
|
||||
}
|
||||
|
||||
if (isTRROnlyFailure && RPMShowTRROnlyFailureError()) {
|
||||
document.body.className = "certerror"; // Shows warning icon
|
||||
pageTitleId = "dns-not-found-trr-only-title";
|
||||
document.l10n.setAttributes(docTitle, pageTitleId, {
|
||||
hostname: HOST_NAME,
|
||||
});
|
||||
bodyTitleId = "dns-not-found-trr-only-title";
|
||||
document.l10n.setAttributes(bodyTitle, bodyTitleId, {
|
||||
hostname: HOST_NAME,
|
||||
});
|
||||
|
||||
shortDesc.textContent = "";
|
||||
|
||||
// enable buttons
|
||||
let trrExceptionButton = document.getElementById("trrExceptionButton");
|
||||
trrExceptionButton.addEventListener("click", () => {
|
||||
RPMSendQuery("Browser:AddTRRExcludedDomain", {
|
||||
// The TRR errors may present options that direct users to settings only available on Firefox Desktop
|
||||
if (RPMIsFirefox()) {
|
||||
if (isTRROnlyFailure) {
|
||||
document.body.className = "certerror"; // Shows warning icon
|
||||
pageTitleId = "dns-not-found-trr-only-title";
|
||||
document.l10n.setAttributes(docTitle, pageTitleId, {
|
||||
hostname: HOST_NAME,
|
||||
}).then(msg => {
|
||||
retryThis(this);
|
||||
});
|
||||
});
|
||||
trrExceptionButton.hidden = false;
|
||||
let trrSettingsButton = document.getElementById("trrSettingsButton");
|
||||
trrSettingsButton.addEventListener("click", () => {
|
||||
RPMSendAsyncMessage("OpenTRRPreferences");
|
||||
});
|
||||
trrSettingsButton.hidden = false;
|
||||
let message = document.getElementById("trrOnlyMessage");
|
||||
document.l10n.setAttributes(
|
||||
message,
|
||||
"neterror-dns-not-found-trr-only-reason",
|
||||
{
|
||||
bodyTitleId = "dns-not-found-trr-only-title";
|
||||
document.l10n.setAttributes(bodyTitle, bodyTitleId, {
|
||||
hostname: HOST_NAME,
|
||||
});
|
||||
|
||||
shortDesc.textContent = "";
|
||||
|
||||
// enable buttons
|
||||
let trrExceptionButton = document.getElementById("trrExceptionButton");
|
||||
trrExceptionButton.addEventListener("click", () => {
|
||||
RPMSendQuery("Browser:AddTRRExcludedDomain", {
|
||||
hostname: HOST_NAME,
|
||||
}).then(msg => {
|
||||
retryThis(this);
|
||||
});
|
||||
});
|
||||
trrExceptionButton.hidden = false;
|
||||
let trrSettingsButton = document.getElementById("trrSettingsButton");
|
||||
trrSettingsButton.addEventListener("click", () => {
|
||||
RPMSendAsyncMessage("OpenTRRPreferences");
|
||||
});
|
||||
trrSettingsButton.hidden = false;
|
||||
let message = document.getElementById("trrOnlyMessage");
|
||||
document.l10n.setAttributes(
|
||||
message,
|
||||
"neterror-dns-not-found-trr-only-reason",
|
||||
{
|
||||
hostname: HOST_NAME,
|
||||
}
|
||||
);
|
||||
|
||||
let skipReason = RPMGetTRRSkipReason();
|
||||
|
||||
let descriptionTag = "neterror-dns-not-found-trr-unknown-problem";
|
||||
let args = { trrDomain: RPMGetTRRDomain() };
|
||||
if (
|
||||
skipReason == "TRR_FAILED" ||
|
||||
skipReason == "TRR_CHANNEL_DNS_FAIL" ||
|
||||
skipReason == "TRR_UNKNOWN_CHANNEL_FAILURE" ||
|
||||
skipReason == "TRR_NET_REFUSED" ||
|
||||
skipReason == "TRR_NET_INTERRUPT" ||
|
||||
skipReason == "TRR_NET_INADEQ_SEQURITY"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-only-could-not-connect";
|
||||
} else if (skipReason == "TRR_TIMEOUT") {
|
||||
descriptionTag = "neterror-dns-not-found-trr-only-timeout";
|
||||
} else if (
|
||||
skipReason == "TRR_IS_OFFLINE" ||
|
||||
skipReason == "TRR_NO_CONNECTIVITY"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-offline";
|
||||
} else if (
|
||||
skipReason == "TRR_NO_ANSWERS" ||
|
||||
skipReason == "TRR_NXDOMAIN"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-unknown-host";
|
||||
} else if (
|
||||
skipReason == "TRR_DECODE_FAILED" ||
|
||||
skipReason == "TRR_SERVER_RESPONSE_ERR"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-server-problem";
|
||||
}
|
||||
);
|
||||
|
||||
let skipReason = RPMGetTRRSkipReason();
|
||||
let description = document.getElementById("trrOnlyDescription");
|
||||
document.l10n.setAttributes(description, descriptionTag, args);
|
||||
|
||||
let descriptionTag = "neterror-dns-not-found-trr-unknown-problem";
|
||||
let args = { trrDomain: RPMGetTRRDomain() };
|
||||
if (
|
||||
skipReason == "TRR_FAILED" ||
|
||||
skipReason == "TRR_CHANNEL_DNS_FAIL" ||
|
||||
skipReason == "TRR_UNKNOWN_CHANNEL_FAILURE" ||
|
||||
skipReason == "TRR_NET_REFUSED" ||
|
||||
skipReason == "TRR_NET_INTERRUPT" ||
|
||||
skipReason == "TRR_NET_INADEQ_SEQURITY"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-only-could-not-connect";
|
||||
} else if (skipReason == "TRR_TIMEOUT") {
|
||||
descriptionTag = "neterror-dns-not-found-trr-only-timeout";
|
||||
} else if (
|
||||
skipReason == "TRR_IS_OFFLINE" ||
|
||||
skipReason == "TRR_NO_CONNECTIVITY"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-offline";
|
||||
} else if (skipReason == "TRR_NO_ANSWERS" || skipReason == "TRR_NXDOMAIN") {
|
||||
descriptionTag = "neterror-dns-not-found-trr-unknown-host";
|
||||
} else if (
|
||||
skipReason == "TRR_DECODE_FAILED" ||
|
||||
skipReason == "TRR_SERVER_RESPONSE_ERR"
|
||||
) {
|
||||
descriptionTag = "neterror-dns-not-found-trr-server-problem";
|
||||
const trrLearnMoreContainer = document.getElementById(
|
||||
"trrLearnMoreContainer"
|
||||
);
|
||||
trrLearnMoreContainer.hidden = false;
|
||||
let learnMoreLink = document.getElementById("trrOnlylearnMoreLink");
|
||||
// This will be replaced at a later point with a link to an offline support page
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1806257
|
||||
learnMoreLink.href =
|
||||
RPMGetFormatURLPref("network.trr_ui.skip_reason_learn_more_url") +
|
||||
skipReason.toLowerCase().replaceAll("_", "-");
|
||||
|
||||
let div = document.getElementById("trrOnlyContainer");
|
||||
div.hidden = false;
|
||||
|
||||
return;
|
||||
} else if (isNativeFallbackWarning) {
|
||||
showNativeFallbackWarning();
|
||||
return;
|
||||
}
|
||||
|
||||
let description = document.getElementById("trrOnlyDescription");
|
||||
document.l10n.setAttributes(description, descriptionTag, args);
|
||||
|
||||
const trrLearnMoreContainer = document.getElementById(
|
||||
"trrLearnMoreContainer"
|
||||
);
|
||||
trrLearnMoreContainer.hidden = false;
|
||||
let learnMoreLink = document.getElementById("trrOnlylearnMoreLink");
|
||||
// This will be replaced at a later point with a link to an offline support page
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1806257
|
||||
learnMoreLink.href =
|
||||
RPMGetFormatURLPref("network.trr_ui.skip_reason_learn_more_url") +
|
||||
skipReason.toLowerCase().replaceAll("_", "-");
|
||||
|
||||
let div = document.getElementById("trrOnlyContainer");
|
||||
div.hidden = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
document.l10n.setAttributes(docTitle, pageTitleId);
|
||||
|
@ -490,6 +505,69 @@ function initPage() {
|
|||
setNetErrorMessageFromCode();
|
||||
}
|
||||
|
||||
function showNativeFallbackWarning() {
|
||||
const docTitle = document.querySelector("title");
|
||||
const bodyTitle = document.querySelector(".title-text");
|
||||
const shortDesc = document.getElementById("errorShortDesc");
|
||||
|
||||
let pageTitleId = "neterror-page-title";
|
||||
let bodyTitleId = gErrorCode + "-title";
|
||||
|
||||
document.body.className = "certerror"; // Shows warning icon
|
||||
pageTitleId = "dns-not-found-native-fallback-title";
|
||||
document.l10n.setAttributes(docTitle, pageTitleId, {
|
||||
hostname: HOST_NAME,
|
||||
});
|
||||
|
||||
bodyTitleId = "dns-not-found-native-fallback-title";
|
||||
document.l10n.setAttributes(bodyTitle, bodyTitleId, {
|
||||
hostname: HOST_NAME,
|
||||
});
|
||||
|
||||
shortDesc.textContent = "";
|
||||
let nativeFallbackIgnoreButton = document.getElementById(
|
||||
"nativeFallbackIgnoreButton"
|
||||
);
|
||||
nativeFallbackIgnoreButton.addEventListener("click", () => {
|
||||
RPMSetBoolPref("network.trr.display_fallback_warning", false);
|
||||
retryThis(nativeFallbackIgnoreButton);
|
||||
});
|
||||
|
||||
nativeFallbackIgnoreButton.hidden = false;
|
||||
let message = document.getElementById("nativeFallbackMessage");
|
||||
document.l10n.setAttributes(
|
||||
message,
|
||||
"neterror-dns-not-found-native-fallback-reason",
|
||||
{
|
||||
hostname: HOST_NAME,
|
||||
}
|
||||
);
|
||||
let skipReason = RPMGetTRRSkipReason();
|
||||
let descriptionTag = "neterror-dns-not-found-trr-unknown-problem";
|
||||
let args = { trrDomain: RPMGetTRRDomain() };
|
||||
|
||||
if (skipReason.includes("HEURISTIC_TRIPPED")) {
|
||||
descriptionTag = "neterror-dns-not-found-native-fallback-heuristic";
|
||||
} else if (skipReason == "TRR_NOT_CONFIRMED") {
|
||||
descriptionTag = "neterror-dns-not-found-native-fallback-not-confirmed";
|
||||
}
|
||||
|
||||
let description = document.getElementById("nativeFallbackDescription");
|
||||
document.l10n.setAttributes(description, descriptionTag, args);
|
||||
|
||||
let learnMoreContainer = document.getElementById(
|
||||
"nativeFallbackLearnMoreContainer"
|
||||
);
|
||||
learnMoreContainer.hidden = false;
|
||||
|
||||
let learnMoreLink = document.getElementById("nativeFallbackLearnMoreLink");
|
||||
learnMoreLink.href =
|
||||
RPMGetFormatURLPref("network.trr_ui.skip_reason_learn_more_url") +
|
||||
skipReason.toLowerCase().replaceAll("_", "-");
|
||||
|
||||
let div = document.getElementById("nativeFallbackContainer");
|
||||
div.hidden = false;
|
||||
}
|
||||
/**
|
||||
* Builds HTML elements from `parts` and appends them to `parent`.
|
||||
*
|
||||
|
|
|
@ -51,6 +51,17 @@
|
|||
<p data-l10n-id="neterror-dns-not-found-trr-only-attackers"> </p>
|
||||
</p>
|
||||
|
||||
<p id="nativeFallbackContainer" hidden="">
|
||||
<p id="nativeFallbackMessage"></p>
|
||||
<div class="native-fallback-message-container">
|
||||
<span id="nativeFallbackDescription"></span>
|
||||
<p id="nativeFallbackLearnMoreContainer" hidden="">
|
||||
<a id="nativeFallbackLearnMoreLink" target="_blank" rel="noopener noreferrer" data-l10n-id="neterror-learn-more-link"></a>
|
||||
</p>
|
||||
</div>
|
||||
<p data-l10n-id="neterror-dns-not-found-native-fallback-attackers"> </p>
|
||||
</p>
|
||||
|
||||
<p id="tlsVersionNotice" hidden=""></p>
|
||||
|
||||
<p id="learnMoreContainer" hidden="">
|
||||
|
@ -81,6 +92,7 @@
|
|||
<button class="primary try-again" data-l10n-id="neterror-try-again-button"></button>
|
||||
<button id="trrExceptionButton" data-l10n-id="neterror-add-exception-button" hidden=""></button>
|
||||
<button id="trrSettingsButton" data-l10n-id="neterror-settings-button" hidden=""></button>
|
||||
<button id="nativeFallbackIgnoreButton" data-l10n-id="neterror-disable-native-feedback-warning" hidden=""></button>
|
||||
</div>
|
||||
|
||||
<div class="advanced-panel-container">
|
||||
|
|
|
@ -110,6 +110,11 @@ dnsNotFound-title = Hmm. We’re having trouble finding that site.
|
|||
dns-not-found-trr-only-title =
|
||||
Possible security risk for { $hostname }.
|
||||
|
||||
# Variables:
|
||||
# $hostname (String) - Hostname of the website to which the user was trying to connect.
|
||||
dns-not-found-native-fallback-title =
|
||||
Possible security risk for { $hostname }.
|
||||
|
||||
fileNotFound-title = File not found
|
||||
fileAccessDenied-title = Access to the file was denied
|
||||
generic-title = Oops.
|
||||
|
|
|
@ -26,6 +26,7 @@ neterror-try-again-button = Try Again
|
|||
neterror-add-exception-button = Always continue for this site
|
||||
neterror-settings-button = Change DNS settings
|
||||
neterror-view-certificate-link = View Certificate
|
||||
neterror-disable-native-feedback-warning = Always continue
|
||||
|
||||
##
|
||||
|
||||
|
@ -65,6 +66,15 @@ neterror-dns-not-found-trr-unknown-host = An address for this website wasn’t f
|
|||
neterror-dns-not-found-trr-server-problem = There was a problem with { $trrDomain }.
|
||||
neterror-dns-not-found-trr-unknown-problem = Unexpected problem.
|
||||
|
||||
## Native fallback specific messages
|
||||
## Variables:
|
||||
## $trrDomain (String) - Hostname of the DNS over HTTPS server that is currently in use.
|
||||
|
||||
neterror-dns-not-found-native-fallback-reason = { -brand-short-name } can’t protect your request for this site’s address through our trusted DNS resolver. Here’s why:
|
||||
neterror-dns-not-found-native-fallback-attackers = You can continue with a DNS resolver that is not secure. However, a third-party might be able to see what websites you visit or send you to an untrusted site.
|
||||
neterror-dns-not-found-native-fallback-heuristic = DNS over HTTPs has been disabled on your network.
|
||||
neterror-dns-not-found-native-fallback-not-confirmed = The connection to { $trrDomain } isn’t ready yet.
|
||||
|
||||
##
|
||||
|
||||
neterror-file-not-found-filename = Check the file name for capitalization or other typing errors.
|
||||
|
|
|
@ -55,6 +55,8 @@ const kAllowedPrefs = new Set([
|
|||
|
||||
"security.tls.version.enable-deprecated",
|
||||
"security.xfocsp.errorReporting.automatic",
|
||||
|
||||
"network.trr.display_fallback_warning",
|
||||
]);
|
||||
|
||||
const kPrefTypeMap = new Map([
|
||||
|
|
|
@ -48,6 +48,7 @@ export let RemotePageAccessManager = {
|
|||
"security.certerrors.permanentOverride",
|
||||
"security.enterprise_roots.auto-enabled",
|
||||
"security.certerror.hideAddException",
|
||||
"network.trr.display_fallback_warning",
|
||||
],
|
||||
RPMGetIntPref: [
|
||||
"services.settings.clock_skew_seconds",
|
||||
|
@ -92,13 +93,18 @@ export let RemotePageAccessManager = {
|
|||
"security.certerror.hideAddException",
|
||||
"security.xfocsp.errorReporting.automatic",
|
||||
"security.xfocsp.errorReporting.enabled",
|
||||
"network.trr.display_fallback_warning",
|
||||
],
|
||||
RPMSetBoolPref: [
|
||||
"security.xfocsp.errorReporting.automatic",
|
||||
"network.trr.display_fallback_warning",
|
||||
],
|
||||
RPMSetBoolPref: ["security.xfocsp.errorReporting.automatic"],
|
||||
RPMAddToHistogram: ["*"],
|
||||
RPMGetInnerMostURI: ["*"],
|
||||
RPMGetHttpResponseHeader: ["*"],
|
||||
RPMIsTRROnlyFailure: ["*"],
|
||||
RPMShowTRROnlyFailureError: ["*"],
|
||||
RPMIsFirefox: ["*"],
|
||||
RPMIsNativeFallbackFailure: ["*"],
|
||||
RPMGetTRRSkipReason: ["*"],
|
||||
RPMGetTRRDomain: ["*"],
|
||||
RPMSendQuery: ["Browser:AddTRRExcludedDomain"],
|
||||
|
|
|
@ -21,7 +21,8 @@ module.exports = {
|
|||
RPMSetBoolPref: false,
|
||||
RPMGetFormatURLPref: false,
|
||||
RPMIsTRROnlyFailure: false,
|
||||
RPMShowTRROnlyFailureError: false,
|
||||
RPMIsFirefox: false,
|
||||
RPMIsNativeFallbackFailure: false,
|
||||
RPMIsWindowPrivate: false,
|
||||
RPMSendAsyncMessage: false,
|
||||
RPMSendQuery: false,
|
||||
|
|
Загрузка…
Ссылка в новой задаче