Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in FedCM
DescriptionInsufficient policy enforcement in FedCM
ComponentFedCM
Bug ClassLogic Error
Tracker502212647
Fix commitffe4e01b5c5c (chromium/src) +36/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
TEST_F
content/browser/webid/delegation/email_verification_request_unittest.cc
modified
TEST
content/browser/webid/delegation/email_verification_request_unittest.cc
modified

Files Changed

  • content/browser/webid/delegation/email_verification_request.cc
  • content/browser/webid/delegation/email_verification_request_unittest.cc
From ffe4e01b5c5c58dfb8c811d141480ac496b4fcba Mon Sep 17 00:00:00 2001
From: Christian Biesinger <[email protected]>
Date: Tue, 12 May 2026 11:50:58 -0700
Subject: [PATCH] [EVP] Disallow opaque origins

Prevent Email Verification Protocol (EVP) from generating browser-signed
assertions for opaque-origin frames, avoiding audience collapse to "null".

[email protected]

Fixed: 502212647
Change-Id: I778134f302a119796aca7a8cbfeccdd9f956c33a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7829839
Commit-Queue: Christian Biesinger <[email protected]>
Auto-Submit: Christian Biesinger <[email protected]>
Reviewed-by: Sam Goto <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1629487}
---

diff --git a/content/browser/webid/delegation/email_verification_request.cc b/content/browser/webid/delegation/email_verification_request.cc
index 396a894..9e631934 100644
--- a/content/browser/webid/delegation/email_verification_request.cc
+++ b/content/browser/webid/delegation/email_verification_request.cc
@@ -106,6 +106,11 @@
     const std::string& email,
     const std::string& nonce,
     EmailVerifier::OnEmailVerifiedCallback callback) {
+  if (render_frame_host_->GetLastCommittedOrigin().opaque()) {
+    std::move(callback).Run(std::nullopt);
+    return;
+  }
+
   // Step 3: Token Request
 
   // Step 3.1: the browser extracts the domain from the email address and
diff --git a/content/browser/webid/delegation/email_verification_request_unittest.cc b/content/browser/webid/delegation/email_verification_request_unittest.cc
index b1d09378..ab6ced6 100644
--- a/content/browser/webid/delegation/email_verification_request_unittest.cc
+++ b/content/browser/webid/delegation/email_verification_request_unittest.cc
@@ -77,6 +77,8 @@
 };
 
 TEST_F(EmailVerificationRequestTest, SuccessfulVerification) {
+  NavigateAndCommit(GURL("https://rp.example.com"));
+
   auto mock_dns_request_ptr = std::make_unique<NiceMock<MockDnsRequest>>();
   NiceMock<MockDnsRequest>* mock_dns_request_ = mock_dns_request_ptr.get();
   auto mock_network_manager_ptr =
@@ -211,6 +213,8 @@
 }
 
 TEST_F(EmailVerificationRequestTest, CrossOriginIssuanceEndpointRejected) {
+  NavigateAndCommit(GURL("https://rp.example.com"));
+
   auto mock_dns_request_ptr = std::make_unique<NiceMock<MockDnsRequest>>();
   NiceMock<MockDnsRequest>* mock_dns_request_ = mock_dns_request_ptr.get();
   auto mock_network_manager_ptr =
@@ -253,6 +257,33 @@
   EXPECT_FALSE(token.has_value());
 }
 
+TEST_F(EmailVerificationRequestTest, OpaqueOriginRejected) {
+  NavigateAndCommit(GURL("data:text/html,<html></html>"));
+
+  auto mock_dns_request_ptr = std::make_unique<NiceMock<MockDnsRequest>>();
+  NiceMock<MockDnsRequest>* mock_dns_request_ = mock_dns_request_ptr.get();
+  auto mock_network_manager_ptr =
+      std::make_unique<NiceMock<MockEmailVerifierNetworkRequestManager>>();
+  NiceMock<MockEmailVerifierNetworkRequestManager>* mock_network_manager_ =
+      mock_network_manager_ptr.get();
+
+  webid::EmailVerificationRequest email_verification_request_(
+      std::move(mock_network_manager_ptr), std::move(mock_dns_request_ptr),
+      static_cast<RenderFrameHostImpl*>(main_rfh())->GetSafeRef());
+
+  const std::string kEmail = "[email protected]";
+  const std::string kNonce = "test_nonce";
+
+  EXPECT_CALL(*mock_dns_request_, SendRequest).Times(0);
+  EXPECT_CALL(*mock_network_manager_, FetchWellKnown).Times(0);
+  EXPECT_CALL(*mock_network_manager_, SendTokenRequest).Times(0);
+
+  base::test::TestFuture<std::optional<std::string>> future;
+  email_verification_request_.Send(kEmail, kNonce, future.GetCallback());
+  std::optional<std::string> token = future.Get();
+  EXPECT_FALSE(token.has_value());
+}
+
 TEST(EmailVerificationRequestStaticTest, ValidEmail) {
   EXPECT_EQ(webid::GetDomainFromEmail("[email protected]"), "example.com");
 }
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/content/browser/webid/delegation/email_verification_request_unittest.cc b/content/browser/webid/delegation/email_verification_request_unittest.cc
index b1d09378..ab6ced6 100644
--- a/content/browser/webid/delegation/email_verification_request_unittest.cc
+++ b/content/browser/webid/delegation/email_verification_request_unittest.cc
@@ -77,6 +77,8 @@
 };
 
 TEST_F(EmailVerificationRequestTest, SuccessfulVerification) {
+  NavigateAndCommit(GURL("https://rp.example.com"));
+
   auto mock_dns_request_ptr = std::make_unique<NiceMock<MockDnsRequest>>();
   NiceMock<MockDnsRequest>* mock_dns_request_ = mock_dns_request_ptr.get();
   auto mock_network_manager_ptr =
@@ -211,6 +213,8 @@
 }
 
 TEST_F(EmailVerificationRequestTest, CrossOriginIssuanceEndpointRejected) {
+  NavigateAndCommit(GURL("https://rp.example.com"));
+
   auto mock_dns_request_ptr = std::make_unique<NiceMock<MockDnsRequest>>();
   NiceMock<MockDnsRequest>* mock_dns_request_ = mock_dns_request_ptr.get();
   auto mock_network_manager_ptr =
@@ -253,6 +257,33 @@
   EXPECT_FALSE(token.has_value());
 }
 
+TEST_F(EmailVerificationRequestTest, OpaqueOriginRejected) {
+  NavigateAndCommit(GURL("data:text/html,<html></html>"));
+
+  auto mock_dns_request_ptr = std::make_unique<NiceMock<MockDnsRequest>>();
+  NiceMock<MockDnsRequest>* mock_dns_request_ = mock_dns_request_ptr.get();
+  auto mock_network_manager_ptr =
+      std::make_unique<NiceMock<MockEmailVerifierNetworkRequestManager>>();
+  NiceMock<MockEmailVerifierNetworkRequestManager>* mock_network_manager_ =
+      mock_network_manager_ptr.get();
+
+  webid::EmailVerificationRequest email_verification_request_(
+      std::move(mock_network_manager_ptr), std::move(mock_dns_request_ptr),
+      static_cast<RenderFrameHostImpl*>(main_rfh())->GetSafeRef());
+
+  const std::string kEmail = "[email protected]";
+  const std::string kNonce = "test_nonce";
+
+  EXPECT_CALL(*mock_dns_request_, SendRequest).Times(0);
+  EXPECT_CALL(*mock_network_manager_, FetchWellKnown).Times(0);
+  EXPECT_CALL(*mock_network_manager_, SendTokenRequest).Times(0);
+
+  base::test::TestFuture<std::optional<std::string>> future;
+  email_verification_request_.Send(kEmail, kNonce, future.GetCallback());
+  std::optional<std::string> token = future.Get();
+  EXPECT_FALSE(token.has_value());
+}
+
 TEST(EmailVerificationRequestStaticTest, ValidEmail) {
   EXPECT_EQ(webid::GetDomainFromEmail("[email protected]"), "example.com");
 }
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.