Bug 1625156 - Error page for HTTPS Only Mode. r=fluent-reviewers,ckerschb,nhnt11,flod,nika,johannh,mattwoodrow

Differential Revision: https://phabricator.services.mozilla.com/D72129
This commit is contained in:
JulianWels 2020-05-26 11:45:21 +00:00
parent 3847626318
commit 2cc2e49495
32 changed files with 419 additions and 5 deletions

View File

@ -1505,8 +1505,14 @@ function _loadURI(browser, uri, params = {}) {
uri = "about:blank";
}
let { triggeringPrincipal, referrerInfo, postData, userContextId, csp } =
params || {};
let {
triggeringPrincipal,
referrerInfo,
postData,
userContextId,
csp,
isHttpsOnlyModeUpgradeExempt,
} = params || {};
let loadFlags =
params.loadFlags || params.flags || Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
let hasValidUserGestureActivation =
@ -1553,6 +1559,7 @@ function _loadURI(browser, uri, params = {}) {
referrerInfo,
postData,
hasValidUserGestureActivation,
isHttpsOnlyModeUpgradeExempt,
};
try {
if (!mustChangeProcess) {

View File

@ -76,6 +76,10 @@ static const RedirEntry kRedirMap[] = {
#endif
{"credits", "https://www.mozilla.org/credits/",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT},
{"httpsonlyerror", "chrome://global/content/httpsonlyerror/errorpage.html",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT},
{"license", "chrome://global/content/license.html",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT},
{"logo", "chrome://branding/content/about.png",

View File

@ -73,6 +73,7 @@
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/ChildSHistory.h"
#include "mozilla/dom/nsCSPContext.h"
#include "mozilla/dom/nsHTTPSOnlyUtils.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/dom/JSWindowActorChild.h"
#include "mozilla/ipc/ProtocolUtils.h"
@ -3693,6 +3694,18 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
}
}
// If the HTTPS-Only Mode upgraded this request and the upgrade might have
// caused this error, we replace the error-page with about:httpsonlyerror
if (aFailedChannel && nsHTTPSOnlyUtils::CouldBeHttpsOnlyError(aError)) {
nsCOMPtr<nsILoadInfo> loadInfo = aFailedChannel->LoadInfo();
uint32_t httpsOnlyStatus = loadInfo->GetHttpsOnlyStatus();
if ((httpsOnlyStatus &
nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_REGISTERED) &&
!(httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_EXEMPT)) {
errorPage.AssignLiteral("httpsonlyerror");
}
}
if (nsCOMPtr<nsILoadURIDelegate> loadURIDelegate = GetLoadURIDelegate()) {
nsCOMPtr<nsIURI> errorPageURI;
rv = loadURIDelegate->HandleLoadError(aURI, aError,
@ -9159,6 +9172,16 @@ nsIPrincipal* nsDocShell::GetInheritedPrincipal(
aLoadInfo->SetIsFormSubmission(true);
}
// If the HTTPS-Only mode is enabled, every insecure request gets upgraded to
// HTTPS by default. This behavior can be disabled through the loadinfo flag
// HTTPS_ONLY_EXEMPT.
if (aLoadState->IsHttpsOnlyModeUpgradeExempt() &&
mozilla::StaticPrefs::dom_security_https_only_mode()) {
uint32_t httpsOnlyStatus = aLoadInfo->GetHttpsOnlyStatus();
httpsOnlyStatus |= nsILoadInfo::HTTPS_ONLY_EXEMPT;
aLoadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
}
nsCOMPtr<nsIChannel> channel;
aRv = CreateRealChannelForDocument(getter_AddRefs(channel), aLoadState->URI(),
aLoadInfo, aCallbacks, aLoadFlags, srcdoc,

View File

@ -92,6 +92,7 @@ nsDocShellLoadState::nsDocShellLoadState(nsIURI* aURI)
mHasValidUserGestureActivation(false),
mTypeHint(VoidCString()),
mFileName(VoidString()),
mIsHttpsOnlyModeUpgradeExempt(false),
mIsFromProcessingFrameAttributes(false),
mLoadIdentifier(0) {
MOZ_ASSERT(aURI, "Cannot create a LoadState with a null URI!");
@ -116,6 +117,7 @@ nsDocShellLoadState::nsDocShellLoadState(
mHasValidUserGestureActivation = aLoadState.HasValidUserGestureActivation();
mTypeHint = aLoadState.TypeHint();
mFileName = aLoadState.FileName();
mIsHttpsOnlyModeUpgradeExempt = aLoadState.IsHttpsOnlyModeUpgradeExempt();
mIsFromProcessingFrameAttributes =
aLoadState.IsFromProcessingFrameAttributes();
mReferrerInfo = aLoadState.ReferrerInfo();
@ -165,6 +167,7 @@ nsDocShellLoadState::nsDocShellLoadState(const nsDocShellLoadState& aOther)
mHasValidUserGestureActivation(aOther.mHasValidUserGestureActivation),
mTypeHint(aOther.mTypeHint),
mFileName(aOther.mFileName),
mIsHttpsOnlyModeUpgradeExempt(aOther.mIsHttpsOnlyModeUpgradeExempt),
mIsFromProcessingFrameAttributes(aOther.mIsFromProcessingFrameAttributes),
mPendingRedirectedChannel(aOther.mPendingRedirectedChannel),
mOriginalURIString(aOther.mOriginalURIString),
@ -349,6 +352,8 @@ nsresult nsDocShellLoadState::CreateFromLoadURIOptions(
if (aLoadURIOptions.mCancelContentJSEpoch) {
loadState->SetCancelContentJSEpoch(aLoadURIOptions.mCancelContentJSEpoch);
}
loadState->SetIsHttpsOnlyModeUpgradeExempt(
aLoadURIOptions.mIsHttpsOnlyModeUpgradeExempt);
if (fixupInfo) {
nsAutoString searchProvider, keyword;
@ -601,6 +606,14 @@ void nsDocShellLoadState::SetFileName(const nsAString& aFileName) {
mFileName = aFileName;
}
bool nsDocShellLoadState::IsHttpsOnlyModeUpgradeExempt() const {
return mIsHttpsOnlyModeUpgradeExempt;
}
void nsDocShellLoadState::SetIsHttpsOnlyModeUpgradeExempt(bool aIsExempt) {
mIsHttpsOnlyModeUpgradeExempt = aIsExempt;
}
nsresult nsDocShellLoadState::SetupInheritingPrincipal(
BrowsingContext::Type aType,
const mozilla::OriginAttributes& aOriginAttributes) {
@ -863,6 +876,7 @@ DocShellLoadStateInit nsDocShellLoadState::Serialize() {
loadState.HasValidUserGestureActivation() = mHasValidUserGestureActivation;
loadState.TypeHint() = mTypeHint;
loadState.FileName() = mFileName;
loadState.IsHttpsOnlyModeUpgradeExempt() = mIsHttpsOnlyModeUpgradeExempt;
loadState.IsFromProcessingFrameAttributes() =
mIsFromProcessingFrameAttributes;
loadState.URI() = mURI;

View File

@ -198,6 +198,10 @@ class nsDocShellLoadState final {
void SetFileName(const nsAString& aFileName);
bool IsHttpsOnlyModeUpgradeExempt() const;
void SetIsHttpsOnlyModeUpgradeExempt(bool aIsExempt);
// Give the type of DocShell we're loading into (chrome/content/etc) and
// origin attributes for the URI we're loading, figure out if we should
// inherit our principal from the document the load was requested from, or
@ -393,6 +397,10 @@ class nsDocShellLoadState final {
// mFileName.IsVoid() should return true.
nsString mFileName;
// If the HTTPS-Only mode is enabled, every insecure request gets upgraded to
// HTTPS by default. The load is exempt from that if this flag is set to true.
bool mIsHttpsOnlyModeUpgradeExempt;
// This will be true if this load is triggered by attribute changes.
// See nsILoadInfo.isFromProcessingFrameAttributes
bool mIsFromProcessingFrameAttributes;

View File

@ -13,6 +13,7 @@ about_pages = [
'crashcontent',
'crashparent',
'credits',
'httpsonlyerror',
'license',
'logo',
'memory',
@ -184,4 +185,4 @@ else:
'init_method': 'Init',
'processes': ProcessSelector.ALLOW_IN_SOCKET_PROCESS,
},
]
]

View File

@ -1346,6 +1346,7 @@ Document::Document(const char* aContentType)
mHasUserInteractionTimerScheduled(false),
mStackRefCnt(0),
mUpdateNestLevel(0),
mHttpsOnlyStatus(nsILoadInfo::HTTPS_ONLY_UNINITIALIZED),
mViewportType(Unknown),
mViewportFit(ViewportFitType::Auto),
mSubDocuments(nullptr),
@ -3166,6 +3167,11 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mBlockAllMixedContent = loadInfo->GetBlockAllMixedContent();
mBlockAllMixedContentPreloads = mBlockAllMixedContent;
// The HTTPS_ONLY_EXEMPT flag of the HTTPS-Only state gets propagated to all
// sub-resources and sub-documents.
mHttpsOnlyStatus =
loadInfo->GetHttpsOnlyStatus() & nsILoadInfo::HTTPS_ONLY_EXEMPT;
nsresult rv = InitReferrerInfo(aChannel);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -869,6 +869,11 @@ class Document : public nsINode,
return mAncestorPrincipals;
}
/**
* Returns true if exempt from HTTPS-Only Mode upgrade.
*/
uint32_t HttpsOnlyStatus() const { return mHttpsOnlyStatus; }
/**
* Get the list of ancestor outerWindowIDs for a document that correspond to
* the ancestor principals (see above for more details).
@ -4922,6 +4927,10 @@ class Document : public nsINode,
// Our update nesting level
uint32_t mUpdateNestLevel;
// HTTPS-Only Mode Status
// Constants are defined at nsILoadInfo::HTTPS_ONLY_*
uint32_t mHttpsOnlyStatus;
enum ViewportType : uint8_t {
DisplayWidthHeight,
Specified,

View File

@ -265,6 +265,7 @@ struct DocShellLoadStateInit
bool HasValidUserGestureActivation;
nsCString TypeHint;
nsString FileName;
bool IsHttpsOnlyModeUpgradeExempt;
bool IsFromProcessingFrameAttributes;
// The Content Security Policy of the load, that is, the CSP of the entity
// responsible for causing the load to occur. Most likely this is the CSP

View File

@ -111,6 +111,9 @@ parent:
// Update the title of the document in this WindowGlobal.
async UpdateDocumentTitle(nsString aTitle);
// Update the document's HTTPS-Only Mode flags in this WindowGlobal.
async UpdateHttpsOnlyStatus(uint32_t aHttpsOnlyStatus);
/// Send down initial document bit to the parent.
async SetIsInitialDocument(bool aIsInitialDocument);

View File

@ -175,6 +175,8 @@ void WindowGlobalChild::OnNewDocument(Document* aDocument) {
"WindowGlobalParent");
}
SendUpdateHttpsOnlyStatus(aDocument->HttpsOnlyStatus());
// Update window context fields for the newly loaded Document.
WindowContext::Transaction txn;
txn.SetCookieBehavior(

View File

@ -344,6 +344,12 @@ mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateDocumentTitle(
return IPC_OK();
}
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateHttpsOnlyStatus(
uint32_t aHttpsOnlyStatus) {
mHttpsOnlyStatus = aHttpsOnlyStatus;
return IPC_OK();
}
IPCResult WindowGlobalParent::RecvUpdateDocumentHasLoaded(
bool aDocumentHasLoaded) {
mDocumentHasLoaded = aDocumentHasLoaded;

View File

@ -188,6 +188,8 @@ class WindowGlobalParent final : public WindowContext,
void DidBecomeCurrentWindowGlobal(bool aCurrent);
uint32_t HttpsOnlyStatus() { return mHttpsOnlyStatus; }
protected:
const nsAString& GetRemoteType() override;
JSActor::Type GetSide() override { return JSActor::Type::Parent; }
@ -209,6 +211,7 @@ class WindowGlobalParent final : public WindowContext,
mozilla::ipc::IPCResult RecvUpdateDocumentCspSettings(
bool aBlockAllMixedContent, bool aUpgradeInsecureRequests);
mozilla::ipc::IPCResult RecvUpdateDocumentTitle(const nsString& aTitle);
mozilla::ipc::IPCResult RecvUpdateHttpsOnlyStatus(uint32_t aHttpsOnlyStatus);
mozilla::ipc::IPCResult RecvSetIsInitialDocument(bool aIsInitialDocument) {
mIsInitialDocument = aIsInitialDocument;
return IPC_OK();
@ -285,6 +288,9 @@ class WindowGlobalParent final : public WindowContext,
bool mDocumentHasUserInteracted;
bool mBlockAllMixedContent;
bool mUpgradeInsecureRequests;
// HTTPS-Only Mode flags
uint32_t mHttpsOnlyStatus;
};
} // namespace dom

View File

@ -42,7 +42,7 @@ NS_IMETHODIMP
nsHTTPSOnlyStreamListener::OnStopRequest(nsIRequest* request,
nsresult aStatus) {
// DNS errors are unrelated to the HTTPS-Only mode, so they can be ignored.
if (aStatus != NS_ERROR_UNKNOWN_HOST) {
if (nsHTTPSOnlyUtils::CouldBeHttpsOnlyError(aStatus)) {
RecordUpgradeTelemetry(request, aStatus);
LogUpgradeFailure(request, aStatus);
}

View File

@ -4,10 +4,10 @@
* 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/. */
#include "nsHTTPSOnlyUtils.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/net/DNS.h"
#include "nsContentUtils.h"
#include "nsHTTPSOnlyUtils.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
#include "prnetdb.h"
@ -108,6 +108,20 @@ bool nsHTTPSOnlyUtils::ShouldUpgradeWebSocket(nsIURI* aURI,
return true;
}
/* static */
bool nsHTTPSOnlyUtils::CouldBeHttpsOnlyError(nsresult aError) {
// This list of error codes is largely drawn from
// nsDocShell::DisplayLoadError()
return !(NS_ERROR_UNKNOWN_PROTOCOL == aError ||
NS_ERROR_FILE_NOT_FOUND == aError ||
NS_ERROR_FILE_ACCESS_DENIED == aError ||
NS_ERROR_UNKNOWN_HOST == aError || NS_ERROR_PHISHING_URI == aError ||
NS_ERROR_MALWARE_URI == aError || NS_ERROR_UNWANTED_URI == aError ||
NS_ERROR_HARMFUL_URI == aError ||
NS_ERROR_CONTENT_CRASHED == aError ||
NS_ERROR_FRAME_CRASHED == aError);
}
/* ------ Logging ------ */
/* static */

View File

@ -34,6 +34,14 @@ class nsHTTPSOnlyUtils {
bool aFromPrivateWindow,
uint32_t aHttpsOnlyStatus);
/**
* Checks if the error code is on a block-list of codes that are probably not
* related to a HTTPS-Only Mode upgrade.
* @param aError Error Code from Request
* @return false if error is not related to upgrade
*/
static bool CouldBeHttpsOnlyError(nsresult aError);
/**
* Logs localized message to either content console or browser console
* @param aName Localization key

View File

@ -68,6 +68,18 @@ dictionary LoadURIOptions {
*/
boolean hasValidUserGestureActivation = false;
/**
* If the HTTPS-Only mode is enabled, every insecure request gets
* upgraded to HTTPS by default. This behavior can be disabled through
* the loadinfo flag HTTPS_ONLY_EXEMPT. The flag gets carried over to
* the next loadinfo through the loadstate as long as it's a same-origin
* request or if the triggering principal is a system principal.
*
* This flag should only ever be true if coming from the HTTPS-Only Mode
* error page.
*/
boolean isHttpsOnlyModeUpgradeExempt = false;
/**
* If non-0, a value to pass to nsIDocShell::setCancelContentJSEpoch
* when initiating the load.

View File

@ -250,6 +250,9 @@ LoadInfo::LoadInfo(
mDocumentHasUserInteracted =
aLoadingContext->OwnerDoc()->UserHasInteracted();
// Inherit HTTPS-Only Mode flags from parent document
mHttpsOnlyStatus |= aLoadingContext->OwnerDoc()->HttpsOnlyStatus();
// When the element being loaded is a frame, we choose the frame's window
// for the window ID and the frame element's window as the parent
// window. This is the behavior that Chrome exposes to add-ons.
@ -716,6 +719,8 @@ LoadInfo::LoadInfo(dom::CanonicalBrowsingContext* aBrowsingContext,
parentBC->UsePrivateBrowsing());
}
mHttpsOnlyStatus |= parentWGP->HttpsOnlyStatus();
// For chrome BC, the mPrivateBrowsingId remains 0 even its
// UsePrivateBrowsing() is true, so we only update the mPrivateBrowsingId in
// origin attributes if the type of the BC is content.

View File

@ -0,0 +1,13 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["AboutHttpsOnlyErrorChild"];
const { RemotePageChild } = ChromeUtils.import(
"resource://gre/actors/RemotePageChild.jsm"
);
class AboutHttpsOnlyErrorChild extends RemotePageChild {}

View File

@ -0,0 +1,77 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["AboutHttpsOnlyErrorParent"];
const { HomePage } = ChromeUtils.import("resource:///modules/HomePage.jsm");
const { PrivateBrowsingUtils } = ChromeUtils.import(
"resource://gre/modules/PrivateBrowsingUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { SessionStore } = ChromeUtils.import(
"resource:///modules/sessionstore/SessionStore.jsm"
);
class AboutHttpsOnlyErrorParent extends JSWindowActorParent {
get browser() {
return this.browsingContext.top.embedderElement;
}
receiveMessage(aMessage) {
switch (aMessage.name) {
case "goBack":
this.goBackFromErrorPage(this.browser.ownerGlobal);
break;
case "openInsecure":
this.openWebsiteInsecure(this.browser.ownerGlobal);
break;
}
}
goBackFromErrorPage(aWindow) {
if (!aWindow.gBrowser) {
return;
}
let state = JSON.parse(
SessionStore.getTabState(aWindow.gBrowser.selectedTab)
);
if (state.index == 1) {
// If the unsafe page is the first or the only one in history, go to the
// start page.
aWindow.gBrowser.loadURI(this.getDefaultHomePage(aWindow), {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
} else {
aWindow.gBrowser.goBack();
}
}
openWebsiteInsecure(aWindow) {
// HTTPS-Only Mode does an internal redirect from HTTP to HTTPS and
// displays the error page if the request fails. So if we want to load the
// page with the exception, we need to replace http:// with https://
const currentURI = aWindow.gBrowser.currentURI;
const uriString = currentURI.displaySpec.replace("https://", "http://");
aWindow.gBrowser.loadURI(uriString, {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
isHttpsOnlyModeUpgradeExempt: true,
});
}
getDefaultHomePage(win) {
let url = win.BROWSER_NEW_TAB_URL;
if (PrivateBrowsingUtils.isWindowPrivate(win)) {
return url;
}
url = HomePage.getDefault();
// If url is a pipe-delimited set of pages, just take the first one.
if (url.includes("|")) {
url = url.split("|")[0];
}
return url;
}
}

View File

@ -24,6 +24,8 @@ TESTING_JS_MODULES += [
]
FINAL_TARGET_FILES.actors += [
'AboutHttpsOnlyErrorChild.jsm',
'AboutHttpsOnlyErrorParent.jsm',
'AudioPlaybackChild.jsm',
'AudioPlaybackParent.jsm',
'AutoCompleteChild.jsm',

View File

@ -0,0 +1,10 @@
<!-- 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/. -->
<svg height="96" viewBox="0 0 96 96" width="96" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="m54 87h-38.718c-4.1514504-.0042773-8.00579913-2.1539983-10.19089334-5.6838598-2.1850942-3.5298615-2.39050529-7.9383886-.54310666-11.6561402l29.718-59.46c2.0323569-4.06636891 6.1880314-6.63518463 10.734-6.63518463s8.7016431 2.56881572 10.734 6.63518463l19.0437959 38.0875919c-8.4035561 1.5187368-14.7777959 8.8711807-14.7777959 17.7124081v1.0104467c-3.547421 1.6851959-6 5.3009594-6 9.4895533z" fill="#ffe900" fill-rule="nonzero"/>
<path d="m39 27c0-3.3137085 2.6862915-6 6-6s6 2.6862915 6 6v24c0 3.3137085-2.6862915 6-6 6s-6-2.6862915-6-6zm6 49.5c-4.1421356 0-7.5-3.3578644-7.5-7.5s3.3578644-7.5 7.5-7.5 7.5 3.3578644 7.5 7.5-3.3578644 7.5-7.5 7.5z" fill="#3e2800"/>
<path d="m89.2954301 61.9390003c.4560585 1.2683141.7045699 2.6356354.7045699 4.0609997v6h1.5c2.4620372-.0002189 4.4671728 1.9781816 4.5 4.44v15c.0160526 1.203836-.4509571 2.3639032-1.296617 3.2208385-.8456598.8569353-1.99944 1.3392685-3.203383 1.3391615h-27c-2.4852814 0-4.5-2.0147186-4.5-4.5v-15c0-2.4852814 2.0147186-4.5 4.5-4.5h1.5v-6c0-6.627417 5.372583-12 12-12 2.9975478 0 5.7383932 1.0990736 7.8415359 2.9162204l-4.2654615 4.2654616c-.998662-.7424058-2.236069-1.181682-3.5760744-1.181682-3.3137085 0-6 2.6862915-6 6v6h12v-4.7655696z" fill="#b1b1b3" fill-rule="nonzero"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,33 @@
<!-- 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/. -->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; object-src 'none'" />
<link rel="stylesheet" href="chrome://global/skin/in-content/info-pages.css">
<link rel="stylesheet" href="chrome://global/skin/aboutHttpsOnlyError.css">
<link rel="localization" href="toolkit/about/aboutHttpsOnlyError.ftl">
<!-- If the location of the favicon is changed here, the FAVICON_ERRORPAGE_URL symbol in
toolkit/components/places/src/nsFaviconService.h should be updated. -->
<link rel="icon" id="favicon" href="chrome://global/skin/icons/warning.svg"/>
<title data-l10n-id="about-httpsonly-insecure-title"></title>
</head>
<body class="caution">
<main class="container">
<div class="title">
<h1 class="title-text" data-l10n-id="about-httpsonly-insecure-title"></h1>
</div>
<p id="insecure-explanation-unavailable" data-l10n-id="about-httpsonly-insecure-explanation-unavailable"></p>
<p data-l10n-id="about-httpsonly-insecure-explanation-reasons"></p>
<p data-l10n-id="about-httpsonly-insecure-explanation-exception"></p>
<div class="button-container">
<button id="goBack" class="primary" data-l10n-id="about-httpsonly-button-go-back"></button>
<button id="openInsecure" data-l10n-id="about-httpsonly-button-make-exception"></button>
</div>
</main>
<script xmlns="http://www.w3.org/1999/xhtml" src="chrome://global/content/httpsonlyerror/errorpage.js"></script>
</body>
</html>

View File

@ -0,0 +1,63 @@
/* 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/. */
/* eslint-env mozilla/frame-script */
"use strict";
const searchParams = new URLSearchParams(document.documentURI.split("?")[1]);
function initPage() {
if (!searchParams.get("e")) {
document.getElementById("error").remove();
}
const explanation1 = document.getElementById(
"insecure-explanation-unavailable"
);
document.l10n.setAttributes(
explanation1,
"about-httpsonly-insecure-explanation-unavailable",
{ websiteUrl: window.location.hostname }
);
document
.getElementById("openInsecure")
.addEventListener("click", onOpenInsecureButtonClick);
addAutofocus("#goBack", "beforeend");
if (window.top == window) {
document
.getElementById("goBack")
.addEventListener("click", onReturnButtonClick);
} else {
document.getElementById("goBack").remove();
}
}
/* Button Events */
function onOpenInsecureButtonClick() {
RPMSendAsyncMessage("openInsecure");
}
function onReturnButtonClick() {
RPMSendAsyncMessage("goBack");
}
/* Utils */
function addAutofocus(selector, position = "afterbegin") {
if (window.top != window) {
return;
}
var button = document.querySelector(selector);
var parent = button.parentNode;
button.remove();
button.setAttribute("autofocus", "true");
parent.insertAdjacentElement(position, button);
}
/* Initialize Page */
initPage();

View File

@ -0,0 +1,8 @@
# 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/.
toolkit.jar:
content/global/httpsonlyerror/errorpage.html (content/errorpage.html)
content/global/httpsonlyerror/errorpage.js (content/errorpage.js)
content/global/httpsonlyerror/cert-error.svg (content/cert-error.svg)

View File

@ -0,0 +1,10 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
JAR_MANIFESTS += ['jar.mn']
with Files('**'):
BUG_COMPONENT = ("Firefox", "Security")

View File

@ -43,6 +43,7 @@ DIRS += [
'forgetaboutsite',
'fuzzyfox',
'glean',
'httpsonlyerror',
'jsoncpp/src/lib_json',
'kvstore',
'lz4',

View File

@ -0,0 +1,14 @@
# 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/.
about-httpsonly-insecure-title = Secure Connection Unavailable
# Variables:
# $websiteUrl (String) - Url of the website that failed to load. Example: www.example.com
about-httpsonly-insecure-explanation-unavailable = Youre browsing in HTTPS-Only Mode, and a secure HTTPS version of <em>{ $websiteUrl }</em> is not available.
about-httpsonly-insecure-explanation-reasons = Most likely, the website does not support HTTPS, but it is also possible that an attacker is blocking the HTTPS version.
about-httpsonly-insecure-explanation-exception = While the security risk is low, if you decide to visit the HTTP version of the website, you should not enter any sensitive information like passwords, emails, or credit card details.
about-httpsonly-button-make-exception = Accept the Risk and Continue to Site
about-httpsonly-button-go-back = Go Back

View File

@ -42,6 +42,19 @@ let JSPROCESSACTORS = {};
* available at https://firefox-source-docs.mozilla.org/dom/Fission.html#jswindowactor
*/
let JSWINDOWACTORS = {
AboutHttpsOnlyError: {
parent: {
moduleURI: "resource://gre/actors/AboutHttpsOnlyErrorParent.jsm",
},
child: {
moduleURI: "resource://gre/actors/AboutHttpsOnlyErrorChild.jsm",
events: {
DOMWindowCreated: {},
},
},
matches: ["about:httpsonlyerror?*"],
allFrames: true,
},
AudioPlayback: {
parent: {
moduleURI: "resource://gre/actors/AudioPlaybackParent.jsm",

View File

@ -65,6 +65,9 @@ let RemotePageAccessManager = {
RPMIsWindowPrivate: ["*"],
RPMAddToHistogram: ["*"],
},
"about:httpsonlyerror": {
RPMSendAsyncMessage: ["goBack", "openInsecure"],
},
"about:neterror": {
RPMSendAsyncMessage: [
"Browser:EnableOnlineMode",

View File

@ -0,0 +1,37 @@
/* 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/. */
body {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
border: 1em solid #ffe900;
}
button {
padding-block: 0.5em;
}
.title {
background-image: url("chrome://global/content/httpsonlyerror/cert-error.svg");
}
em {
font-style: normal;
font-weight: 600;
}
.button-container {
display: flex;
flex-flow: row wrap;
justify-content: end;
}
@media only screen and (max-width: 480px) {
.button-container button {
width: 100%;
margin: 0.66em 0 0;
}
}

View File

@ -14,6 +14,7 @@ toolkit.jar:
skin/classic/global/about.css (../../shared/about.css)
skin/classic/global/aboutCache.css (../../shared/aboutCache.css)
skin/classic/global/aboutCacheEntry.css (../../shared/aboutCacheEntry.css)
skin/classic/global/aboutHttpsOnlyError.css (../../shared/aboutHttpsOnlyError.css)
skin/classic/global/aboutMemory.css (../../shared/aboutMemory.css)
skin/classic/global/aboutNetworking.css (../../shared/aboutNetworking.css)
skin/classic/global/aboutReader.css (../../shared/aboutReader.css)