mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1653026 - Added HTTPS-Only Mode upgrade info to browser UI state. r=mattwoodrow,necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D86566
This commit is contained in:
parent
18d1af1eb5
commit
341416588c
@ -178,10 +178,9 @@ void CanonicalBrowsingContext::ReplacedBy(
|
||||
mActiveEntry.swap(aNewContext->mActiveEntry);
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::
|
||||
UpdateSecurityStateForLocationOrMixedContentChange() {
|
||||
void CanonicalBrowsingContext::UpdateSecurityState() {
|
||||
if (mSecureBrowserUI) {
|
||||
mSecureBrowserUI->UpdateForLocationOrMixedContentChange();
|
||||
mSecureBrowserUI->RecomputeSecurityFlags();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,8 +213,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
// Called when the current URI changes (from an
|
||||
// nsIWebProgressListener::OnLocationChange event, so that we
|
||||
// can update our security UI for the new location, or when the
|
||||
// mixed content state for our current window is changed.
|
||||
void UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
// mixed content/https-only state for our current window is changed.
|
||||
void UpdateSecurityState();
|
||||
|
||||
void MaybeAddAsProgressListener(nsIWebProgress* aWebProgress);
|
||||
|
||||
|
@ -334,21 +334,23 @@ void WindowContext::Discard() {
|
||||
Group()->Unregister(this);
|
||||
}
|
||||
|
||||
void WindowContext::AddMixedContentSecurityState(uint32_t aStateFlags) {
|
||||
void WindowContext::AddSecurityState(uint32_t aStateFlags) {
|
||||
MOZ_ASSERT(TopWindowContext() == this);
|
||||
MOZ_ASSERT((aStateFlags &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT)) ==
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED |
|
||||
nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED)) ==
|
||||
aStateFlags,
|
||||
"Invalid flags specified!");
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
Canonical()->AddMixedContentSecurityState(aStateFlags);
|
||||
Canonical()->AddSecurityState(aStateFlags);
|
||||
} else {
|
||||
ContentChild* child = ContentChild::GetSingleton();
|
||||
child->SendAddMixedContentSecurityState(this, aStateFlags);
|
||||
child->SendAddSecurityState(this, aStateFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,11 +136,10 @@ class WindowContext : public nsISupports, public nsWrapperCache {
|
||||
|
||||
static void CreateFromIPC(IPCInitializer&& aInit);
|
||||
|
||||
// Add new mixed content security state flags.
|
||||
// These should be some of the four nsIWebProgressListener
|
||||
// 'MIXED' state flags, and should only be called on the
|
||||
// top window context.
|
||||
void AddMixedContentSecurityState(uint32_t aStateFlags);
|
||||
// Add new security state flags.
|
||||
// These should be some of the nsIWebProgressListener 'HTTPS_ONLY_MODE' or
|
||||
// 'MIXED' state flags, and should only be called on the top window context.
|
||||
void AddSecurityState(uint32_t aStateFlags);
|
||||
|
||||
// This function would be called when its corresponding window is activated
|
||||
// by user gesture.
|
||||
|
@ -5820,9 +5820,7 @@ nsDocShell::OnLocationChange(nsIWebProgress* aProgress, nsIRequest* aRequest,
|
||||
// changes the current window global, but that happens before this and we
|
||||
// have a lot of tests that depend on the specific ordering of messages.
|
||||
if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
|
||||
GetBrowsingContext()
|
||||
->Canonical()
|
||||
->UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
GetBrowsingContext()->Canonical()->UpdateSecurityState();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -3167,10 +3167,10 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
mBlockAllMixedContent = loadInfo->GetBlockAllMixedContent();
|
||||
mBlockAllMixedContentPreloads = mBlockAllMixedContent;
|
||||
|
||||
// HTTPS-Only Mode flags
|
||||
// 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;
|
||||
mHttpsOnlyStatus = loadInfo->GetHttpsOnlyStatus();
|
||||
|
||||
nsresult rv = InitReferrerInfo(aChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2688,7 +2688,7 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnLocationChange(
|
||||
// the current window global, but that happens before this and we have a lot
|
||||
// of tests that depend on the specific ordering of messages.
|
||||
if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) {
|
||||
GetBrowsingContext()->UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
GetBrowsingContext()->UpdateSecurityState();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -4017,13 +4017,13 @@ bool ContentParent::DeallocPParentToChildStreamParent(
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvAddMixedContentSecurityState(
|
||||
mozilla::ipc::IPCResult ContentParent::RecvAddSecurityState(
|
||||
const MaybeDiscarded<WindowContext>& aContext, uint32_t aStateFlags) {
|
||||
if (aContext.IsNullOrDiscarded()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
aContext.get()->AddMixedContentSecurityState(aStateFlags);
|
||||
aContext.get()->AddSecurityState(aStateFlags);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -1103,7 +1103,7 @@ class ContentParent final
|
||||
const MaybeDiscarded<WindowContext>& aContext,
|
||||
WindowContext::BaseTransaction&& aTransaction, uint64_t aEpoch);
|
||||
|
||||
mozilla::ipc::IPCResult RecvAddMixedContentSecurityState(
|
||||
mozilla::ipc::IPCResult RecvAddSecurityState(
|
||||
const MaybeDiscarded<WindowContext>& aContext, uint32_t aStateFlags);
|
||||
|
||||
mozilla::ipc::IPCResult RecvFirstIdle();
|
||||
|
@ -1055,7 +1055,7 @@ parent:
|
||||
|
||||
async OpenNotificationSettings(Principal principal);
|
||||
|
||||
async AddMixedContentSecurityState(MaybeDiscardedWindowContext aContext, uint32_t aStateFlags);
|
||||
async AddSecurityState(MaybeDiscardedWindowContext aContext, uint32_t aStateFlags);
|
||||
|
||||
// Request that the ServiceWorkerManager in the parent process create a
|
||||
// notification "click" or "close" event and dispatch it on the relevant
|
||||
|
@ -986,11 +986,11 @@ void WindowGlobalParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
};
|
||||
|
||||
bool hasMixedDisplay =
|
||||
mMixedContentSecurityState &
|
||||
mSecurityState &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT);
|
||||
bool hasMixedActive =
|
||||
mMixedContentSecurityState &
|
||||
mSecurityState &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT);
|
||||
|
||||
@ -1102,24 +1102,26 @@ bool WindowGlobalParent::ShouldTrackSiteOriginTelemetry() {
|
||||
return DocumentPrincipal()->GetIsContentPrincipal();
|
||||
}
|
||||
|
||||
void WindowGlobalParent::AddMixedContentSecurityState(uint32_t aStateFlags) {
|
||||
void WindowGlobalParent::AddSecurityState(uint32_t aStateFlags) {
|
||||
MOZ_ASSERT(TopWindowContext() == this);
|
||||
MOZ_ASSERT((aStateFlags &
|
||||
(nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_DISPLAY_CONTENT |
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT)) ==
|
||||
nsIWebProgressListener::STATE_BLOCKED_MIXED_ACTIVE_CONTENT |
|
||||
nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED |
|
||||
nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED)) ==
|
||||
aStateFlags,
|
||||
"Invalid flags specified!");
|
||||
|
||||
if ((mMixedContentSecurityState & aStateFlags) == aStateFlags) {
|
||||
if ((mSecurityState & aStateFlags) == aStateFlags) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMixedContentSecurityState |= aStateFlags;
|
||||
mSecurityState |= aStateFlags;
|
||||
|
||||
if (GetBrowsingContext()->GetCurrentWindowGlobal() == this) {
|
||||
GetBrowsingContext()->UpdateSecurityStateForLocationOrMixedContentChange();
|
||||
GetBrowsingContext()->UpdateSecurityState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,8 +193,8 @@ class WindowGlobalParent final : public WindowContext,
|
||||
|
||||
uint32_t HttpsOnlyStatus() { return mHttpsOnlyStatus; }
|
||||
|
||||
void AddMixedContentSecurityState(uint32_t aStateFlags);
|
||||
uint32_t GetMixedContentSecurityFlags() { return mMixedContentSecurityState; }
|
||||
void AddSecurityState(uint32_t aStateFlags);
|
||||
uint32_t GetSecurityFlags() { return mSecurityState; }
|
||||
|
||||
nsITransportSecurityInfo* GetSecurityInfo() { return mSecurityInfo; }
|
||||
|
||||
@ -289,7 +289,7 @@ class WindowGlobalParent final : public WindowContext,
|
||||
// includes the activity log for all of the nested subdocuments as well.
|
||||
ContentBlockingLog mContentBlockingLog;
|
||||
|
||||
uint32_t mMixedContentSecurityState = 0;
|
||||
uint32_t mSecurityState = 0;
|
||||
|
||||
Maybe<ClientInfo> mClientInfo;
|
||||
// Fields being mirrored from the corresponding document
|
||||
|
@ -4,13 +4,14 @@
|
||||
* 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 "NSSErrorsService.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozpkix/pkixnss.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHTTPSOnlyStreamListener.h"
|
||||
#include "nsHTTPSOnlyUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsITransportSecurityInfo.h"
|
||||
@ -23,8 +24,18 @@ NS_IMPL_ISUPPORTS(nsHTTPSOnlyStreamListener, nsIStreamListener,
|
||||
nsIRequestObserver)
|
||||
|
||||
nsHTTPSOnlyStreamListener::nsHTTPSOnlyStreamListener(
|
||||
nsIStreamListener* aListener)
|
||||
: mListener(aListener), mCreationStart(mozilla::TimeStamp::Now()) {}
|
||||
nsIStreamListener* aListener, nsILoadInfo* aLoadInfo)
|
||||
: mListener(aListener), mCreationStart(mozilla::TimeStamp::Now()) {
|
||||
RefPtr<mozilla::dom::WindowGlobalParent> wgp =
|
||||
mozilla::dom::WindowGlobalParent::GetByInnerWindowId(
|
||||
aLoadInfo->GetInnerWindowID());
|
||||
// For Top-level document loads (which don't have a requesting window-context)
|
||||
// we compute these flags once we create the Document in nsSecureBrowserUI.
|
||||
if (wgp) {
|
||||
wgp->TopWindowContext()->AddSecurityState(
|
||||
nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPSOnlyStreamListener::OnDataAvailable(nsIRequest* aRequest,
|
||||
@ -42,9 +53,28 @@ NS_IMETHODIMP
|
||||
nsHTTPSOnlyStreamListener::OnStopRequest(nsIRequest* request,
|
||||
nsresult aStatus) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
||||
|
||||
// Note: CouldBeHttpsOnlyError also returns true if there was no error
|
||||
if (nsHTTPSOnlyUtils::CouldBeHttpsOnlyError(channel, aStatus)) {
|
||||
RecordUpgradeTelemetry(request, aStatus);
|
||||
LogUpgradeFailure(request, aStatus);
|
||||
|
||||
// If the request failed and there is a requesting window-context, set
|
||||
// HTTPS-Only state flag to indicate a failed upgrade.
|
||||
// For Top-level document loads (which don't have a requesting
|
||||
// window-context) we simply check in the UI code whether we landed on the
|
||||
// HTTPS-Only error page.
|
||||
if (NS_FAILED(aStatus)) {
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
|
||||
RefPtr<mozilla::dom::WindowGlobalParent> wgp =
|
||||
mozilla::dom::WindowGlobalParent::GetByInnerWindowId(
|
||||
loadInfo->GetInnerWindowID());
|
||||
|
||||
if (wgp) {
|
||||
wgp->TopWindowContext()->AddSecurityState(
|
||||
nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mListener->OnStopRequest(request, aStatus);
|
||||
|
@ -22,7 +22,8 @@ class nsHTTPSOnlyStreamListener : public nsIStreamListener {
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
explicit nsHTTPSOnlyStreamListener(nsIStreamListener* aListener);
|
||||
explicit nsHTTPSOnlyStreamListener(nsIStreamListener* aListener,
|
||||
nsILoadInfo* aLoadInfo);
|
||||
|
||||
private:
|
||||
virtual ~nsHTTPSOnlyStreamListener() = default;
|
||||
|
@ -84,7 +84,7 @@ void nsHTTPSOnlyUtils::PotentiallyFireHttpRequestToShortenTimout(
|
||||
|
||||
// if it's not a GET method, then there is nothing to do here either.
|
||||
nsAutoCString method;
|
||||
Unused << httpChannel->GetRequestMethod(method);
|
||||
mozilla::Unused << httpChannel->GetRequestMethod(method);
|
||||
if (!method.EqualsLiteral("GET")) {
|
||||
return;
|
||||
}
|
||||
@ -495,7 +495,7 @@ TestHTTPAnswerRunnable::Notify(nsITimer* aTimer) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
OriginAttributes attrs = origLoadInfo->GetOriginAttributes();
|
||||
mozilla::OriginAttributes attrs = origLoadInfo->GetOriginAttributes();
|
||||
RefPtr<nsIPrincipal> nullPrincipal =
|
||||
mozilla::NullPrincipal::CreateWithInheritedAttributes(attrs);
|
||||
|
||||
|
@ -898,7 +898,7 @@ nsresult nsMixedContentBlocker::ShouldLoad(bool aHadInsecureImageRedirect,
|
||||
|
||||
// Notify the top WindowContext of the flags we've computed, and it
|
||||
// will handle updating any relevant security UI.
|
||||
topWC->AddMixedContentSecurityState(newState);
|
||||
topWC->AddSecurityState(newState);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -634,7 +634,7 @@ nsresult nsHttpChannel::OnBeforeConnect() {
|
||||
if (httpOnlyStatus &
|
||||
nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED) {
|
||||
RefPtr<nsHTTPSOnlyStreamListener> httpsOnlyListener =
|
||||
new nsHTTPSOnlyStreamListener(mListener);
|
||||
new nsHTTPSOnlyStreamListener(mListener, mLoadInfo);
|
||||
mListener = httpsOnlyListener;
|
||||
|
||||
httpOnlyStatus ^=
|
||||
|
@ -51,7 +51,7 @@ nsSecureBrowserUI::GetState(uint32_t* aState) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsSecureBrowserUI::UpdateForLocationOrMixedContentChange() {
|
||||
void nsSecureBrowserUI::RecomputeSecurityFlags() {
|
||||
// Our BrowsingContext either has a new WindowGlobalParent, or the
|
||||
// existing one has mutated its security state.
|
||||
// Recompute our security state and fire notifications to listeners
|
||||
@ -87,9 +87,17 @@ void nsSecureBrowserUI::UpdateForLocationOrMixedContentChange() {
|
||||
}
|
||||
}
|
||||
|
||||
// Add the mixed content flags from the window
|
||||
// Add upgraded-state flags when request has been
|
||||
// upgraded with HTTPS-Only Mode
|
||||
if (win) {
|
||||
mState |= win->GetMixedContentSecurityFlags();
|
||||
// Check if top-level load has been upgraded
|
||||
uint32_t httpsOnlyStatus = win->HttpsOnlyStatus();
|
||||
if (!(httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UNINITIALIZED) &&
|
||||
!(httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_EXEMPT)) {
|
||||
mState |= nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED;
|
||||
}
|
||||
// Add the secruity flags from the window
|
||||
mState |= win->GetSecurityFlags();
|
||||
}
|
||||
|
||||
// If we have loaded mixed content and this is a secure page,
|
||||
|
@ -39,7 +39,7 @@ class nsSecureBrowserUI : public nsISecureBrowserUI,
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISECUREBROWSERUI
|
||||
|
||||
void UpdateForLocationOrMixedContentChange();
|
||||
void RecomputeSecurityFlags();
|
||||
|
||||
protected:
|
||||
virtual ~nsSecureBrowserUI() = default;
|
||||
|
@ -354,6 +354,18 @@ interface nsIWebProgressListener : nsISupports
|
||||
const unsigned long STATE_LOADED_SOCIALTRACKING_CONTENT = 0x00020000;
|
||||
const unsigned long STATE_UNBLOCKED_UNSAFE_CONTENT = 0x00000010;
|
||||
|
||||
/**
|
||||
* Flag for HTTPS-Only Mode upgrades
|
||||
*
|
||||
* STATE_HTTPS_ONLY_MODE_UPGRADED
|
||||
* When a request has been upgraded by HTTPS-Only Mode
|
||||
*
|
||||
* STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED
|
||||
* When an upgraded request failed.
|
||||
*/
|
||||
const unsigned long STATE_HTTPS_ONLY_MODE_UPGRADED = 0x00400000;
|
||||
const unsigned long STATE_HTTPS_ONLY_MODE_UPGRADE_FAILED = 0x00800000;
|
||||
|
||||
/**
|
||||
* Notification indicating the state has changed for one of the requests
|
||||
* associated with aWebProgress.
|
||||
|
Loading…
Reference in New Issue
Block a user