commit d28568cb3ae26dad261a006fef4fbc62a81504b6
parent 1d276bc57ffe77e0365385c9c08fb27708f56934
Author: Malte Jürgens <maltejur@mozilla.com>
Date: Thu, 13 Nov 2025 13:54:09 +0000
Bug 1968527 - Don't HTTPS-Only/-First downgrade during client cert dialog r=keeler
Before displaying the client cert dialog, add a
HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS flag to the loadinfo of the current load
of the browsing context associated with the dialog, indicating HTTPS-Only/First
should not downgrade the load anymore. Otherwise, we will currently just cancel
the client cert dialog and show the HTTPS-Only error page after 2.2s.
Differential Revision: https://phabricator.services.mozilla.com/D271795
Diffstat:
1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/security/manager/ssl/TLSClientAuthCertSelection.cpp b/security/manager/ssl/TLSClientAuthCertSelection.cpp
@@ -36,8 +36,10 @@
#include "cert_storage/src/cert_storage.h"
#include "mozilla/Logging.h"
#include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/glean/SecurityManagerSslMetrics.h"
#include "mozilla/ipc/Endpoint.h"
+#include "mozilla/net/DocumentLoadListener.h"
#include "mozilla/net/SocketProcessBackgroundChild.h"
#include "mozilla/psm/SelectTLSClientAuthCertChild.h"
#include "mozilla/psm/SelectTLSClientAuthCertParent.h"
@@ -727,15 +729,36 @@ SelectClientAuthCertificate::Run() {
DispatchContinuation(std::move(selectedCertBytes));
return NS_ERROR_FAILURE;
}
- nsCOMPtr<nsILoadContext> loadContext = nullptr;
- if (mBrowserId != 0) {
- loadContext =
+
+ RefPtr<mozilla::dom::BrowsingContext> browsingContext;
+ if (mBrowserId) {
+ browsingContext =
mozilla::dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId);
}
+
+ // Prevent HTTPS-Only/-First from downgrading the load in the browsing context
+ // while the dialog is open by setting HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS
+ // early. Otherwise this would only get set once
+ // DocumentLoadListener::DoOnStartRequest is reached.
+ if (browsingContext) {
+ RefPtr<net::DocumentLoadListener> loadListener =
+ browsingContext->Canonical()->GetCurrentLoad();
+ if (loadListener) {
+ nsCOMPtr<nsIHttpChannel> channel =
+ do_QueryInterface(loadListener->GetChannel());
+ if (channel) {
+ nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
+ uint32_t httpsOnlyStatus = loadInfo->GetHttpsOnlyStatus();
+ httpsOnlyStatus |= nsILoadInfo::HTTPS_ONLY_TOP_LEVEL_LOAD_IN_PROGRESS;
+ loadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
+ }
+ }
+ }
+
RefPtr<nsIClientAuthDialogCallback> callback(
new ClientAuthDialogCallback(this));
nsresult rv = clientAuthDialogService->ChooseCertificate(
- mInfo.HostName(), certArray, loadContext, mCANames, callback);
+ mInfo.HostName(), certArray, browsingContext, mCANames, callback);
if (NS_FAILED(rv)) {
DispatchContinuation(std::move(selectedCertBytes));
return rv;