Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactImproper certificate validation in FedCM
DescriptionImproper certificate validation in FedCM
ComponentFedCM
Bug ClassLogic Error
Tracker540072282
Fix commit4906428f67d6 (chromium/src) +37/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-09-08

Changed Functions

FunctionChangeNotes
TEST_F
content/common/webid/identity_url_loader_throttle_unittest.cc
modified

Files Changed

  • content/common/BUILD.gn
  • content/common/DEPS
  • content/common/webid/identity_url_loader_throttle.cc
  • content/common/webid/identity_url_loader_throttle_unittest.cc
From 4906428f67d6d47d3cb5341b7517389e889181ed Mon Sep 17 00:00:00 2001
From: Nicolás Peña <npm@chromium.org>
Date: Thu, 06 Aug 2026 07:53:37 -0700
Subject: [PATCH] [FedCM] Reject Set-Login headers on connections with cert errors

IdentityUrlLoaderThrottle handles Set-Login response headers to set
persistent origin-keyed IdP sign-in status. Currently, it checks
whether the origin is potentially trustworthy, but does not check
whether the connection has TLS certificate errors.

An attacker MITM-ing an HTTPS connection with a self-signed or
invalid certificate could cause Set-Login headers to be processed
if the user clicked past the certificate error interstitial. This
could persist origin-keyed sign-in status, leading to cross-site
denial of service or state confusion.

This CL early-returns in IdentityUrlLoaderThrottle when
net::IsCertStatusError(response_head.cert_status) is true, matching
the pattern used by other security-sensitive response headers.

Bug: 540072282
Change-Id: I4693599760fa036b0c1194e84816e900f7bdd205
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8198686
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: Yi Gu <yigu@chromium.org>
Commit-Queue: Nicolás Peña <npm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1674972}
---

diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 264cdb4d..6db21bb 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -224,6 +224,7 @@
     "//build:branding_buildflags",
     "//components/discardable_memory/common",
     "//components/input",
+    "//components/network_session_configurator/common",
     "//components/services/filesystem/public/mojom",
     "//components/tracing:tracing_config",
     "//content:content_resources",
diff --git a/content/common/DEPS b/content/common/DEPS
index fff9622..6379910 100644
--- a/content/common/DEPS
+++ b/content/common/DEPS
@@ -2,6 +2,7 @@
   "-storage/browser",
 
   "+components/discardable_memory/common",
+  "+components/network_session_configurator/common",
   "+components/viz/common",
   "+device/base/synchronization",
   "+services/data_decoder/public/cpp",
diff --git a/content/common/webid/identity_url_loader_throttle.cc b/content/common/webid/identity_url_loader_throttle.cc
index 7f396480..c6e479e 100644
--- a/content/common/webid/identity_url_loader_throttle.cc
+++ b/content/common/webid/identity_url_loader_throttle.cc
@@ -8,14 +8,17 @@
 #include <string_view>
 
 #include "base/auto_reset.h"
+#include "base/command_line.h"
 #include "base/functional/bind.h"
 #include "base/strings/string_split.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
+#include "components/network_session_configurator/common/network_switches.h"
 #include "content/common/features.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
+#include "net/cert/cert_status_flags.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/structured_headers.h"
 #include "services/data_decoder/public/cpp/data_decoder.h"
@@ -139,6 +142,12 @@
     return;
   }
 
+  if (net::IsCertStatusError(response_head.cert_status) &&
+      !base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIgnoreCertificateErrors)) {
+    return;
+  }
+
   // TODO(crbug.com/40236764):
   // - Limit to toplevel frames
   // - Decide whether to limit to same-origin
diff --git a/content/common/webid/identity_url_loader_throttle_unittest.cc b/content/common/webid/identity_url_loader_throttle_unittest.cc
index da7a8475..b972da46 100644
--- a/content/common/webid/identity_url_loader_throttle_unittest.cc
+++ b/content/common/webid/identity_url_loader_throttle_unittest.cc
@@ -11,6 +11,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/web_identity.h"
+#include "net/cert/cert_status_flags.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/structured_headers.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
@@ -354,4 +355,29 @@
   EXPECT_TRUE(result_item->item.is_integer());
 }
 
+TEST_F(IdentityUrlLoaderThrottleTest, CertError) {
+  TestDelegate delegate;
+  std::unique_ptr<blink::URLLoaderThrottle> throttle =
+      MaybeCreateIdentityUrlLoaderThrottle(CreateCallback(),
+                                           CreateParseCallback());
+  ASSERT_NE(nullptr, throttle);
+  throttle->set_delegate(&delegate);
+
+  network::ResourceRequest request;
+  request.url = GURL("https://accounts.idp.example/");
+  bool defer = false;
+
+  throttle->WillStartRequest(&request, &defer);
+  EXPECT_FALSE(defer);
+
+  network::mojom::URLResponseHead response_head;
+  response_head.cert_status = net::CERT_STATUS_DATE_INVALID;
+  response_head.headers = net::HttpResponseHeaders::TryToCreate(
+      "HTTP/1.1 200 OK\nSet-Login: logged-in\n");
+  throttle->WillProcessResponse(request.url, &response_head, &defer);
+  EXPECT_FALSE(defer);
+
+  EXPECT_EQ(0, cb_num_calls_);
+}
+
 }  // namespace content
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/content/common/webid/identity_url_loader_throttle_unittest.cc b/content/common/webid/identity_url_loader_throttle_unittest.cc
index da7a8475..b972da46 100644
--- a/content/common/webid/identity_url_loader_throttle_unittest.cc
+++ b/content/common/webid/identity_url_loader_throttle_unittest.cc
@@ -11,6 +11,7 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/web_identity.h"
+#include "net/cert/cert_status_flags.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/structured_headers.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
@@ -354,4 +355,29 @@
   EXPECT_TRUE(result_item->item.is_integer());
 }
 
+TEST_F(IdentityUrlLoaderThrottleTest, CertError) {
+  TestDelegate delegate;
+  std::unique_ptr<blink::URLLoaderThrottle> throttle =
+      MaybeCreateIdentityUrlLoaderThrottle(CreateCallback(),
+                                           CreateParseCallback());
+  ASSERT_NE(nullptr, throttle);
+  throttle->set_delegate(&delegate);
+
+  network::ResourceRequest request;
+  request.url = GURL("https://accounts.idp.example/");
+  bool defer = false;
+
+  throttle->WillStartRequest(&request, &defer);
+  EXPECT_FALSE(defer);
+
+  network::mojom::URLResponseHead response_head;
+  response_head.cert_status = net::CERT_STATUS_DATE_INVALID;
+  response_head.headers = net::HttpResponseHeaders::TryToCreate(
+      "HTTP/1.1 200 OK\nSet-Login: logged-in\n");
+  throttle->WillProcessResponse(request.url, &response_head, &defer);
+  EXPECT_FALSE(defer);
+
+  EXPECT_EQ(0, cb_num_calls_);
+}
+
 }  // namespace content
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.