Low CVSS 4.3 chrome Policy Bypass 🔧 Commit mapped

Overview

Low
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactPolicy bypass in Chrome for iOS
DescriptionPolicy bypass in Chrome for iOS
ComponentChrome for iOS
Sub-componentiOS
Bug ClassPolicy Bypass
Tracker511808800
Fix commitfdb4fcf96972 (chromium/src) +51/-1
CWECWE-602
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-05-10 (per vendor advisory)
Fix landed2026-05-21 (public git)
Disclosed2026-06-30
Patch gap40 days — fix public in source before the advisory

Changed Functions

FunctionChangeNotes
if
ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
modified
TEST_F
ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
modified

Files Changed

  • ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
  • ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
From fdb4fcf96972c262ecc007b562ee8ef077312ebe Mon Sep 17 00:00:00 2001
From: Quentin Pubert <qpubert@google.com>
Date: Thu, 21 May 2026 03:39:58 -0700
Subject: [PATCH] [iOS][ReaderMode] Default link forwarding to ReferrerPolicyStrictOriginWhenCrossOrigin

This changes the default ReferrerPolicy used in ReaderModeContentDidCancelRequest from ReferrerPolicyDefault to ReferrerPolicyStrictOriginWhenCrossOrigin. This prevents potential Referrer-Policy bypass and URL/sensitive parameter leaks when navigating to cross-origin destinations from Reader Mode.

Bug: 511808800
Change-Id: Ic3fb923f621a23d447b3fc93f0fe4f8b8be5ca1e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7864202
Reviewed-by: Olivier Robin <olivierrobin@chromium.org>
Commit-Queue: Olivier Robin <olivierrobin@chromium.org>
Auto-Submit: Quentin Pubert <qpubert@google.com>
Commit-Queue: Quentin Pubert <qpubert@google.com>
Cr-Commit-Position: refs/heads/main@{#1634159}
---

diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
index 5221dc6f..275008d4 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.mm
@@ -378,7 +378,7 @@
   if (referrer_value) {
     NSURL* referrer_url = [NSURL URLWithString:referrer_value];
     params.referrer.url = net::GURLWithNSURL(referrer_url);
-    params.referrer.policy = web::ReferrerPolicyDefault;
+    params.referrer.policy = web::ReferrerPolicyStrictOriginWhenCrossOrigin;
   }
   params.transition_type = request_info.transition_type;
   web_state_->GetNavigationManager()->LoadURLWithParams(params);
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
index e5f1c9d..e10a6a4 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
@@ -991,6 +991,56 @@
   EXPECT_EQ(0u, infobar_manager->infobars().size());
 }
 
+// Tests that when Reader Mode cancels a request, the request is forwarded to
+// the navigation manager with the correct
+// ReferrerPolicyStrictOriginWhenCrossOrigin policy.
+TEST_F(ReaderModeTabHelperTest, ReaderModeContentDidCancelRequestForwarding) {
+  web_state()->WasShown();
+  GURL test_url("https://test.url/");
+  LoadWebpage(web_state(), test_url);
+  SetReaderModeState(web_state(), test_url,
+                     ReaderModeHeuristicResult::kReaderModeEligible, "Content");
+  WaitForPageLoadDelayAndRunUntilIdle();
+
+  // Activate Reader Mode.
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
+  WaitForAvailableReaderModeContentInWebState(web_state());
+
+  // Ensure the host tab navigation manager has not been called yet.
+  web::FakeNavigationManager* navigation_manager =
+      static_cast<web::FakeNavigationManager*>(
+          web_state()->GetNavigationManager());
+  ASSERT_FALSE(navigation_manager->LoadURLWithParamsWasCalled());
+
+  // Simulate a navigation cancellation with a referrer.
+  NSMutableURLRequest* request = [NSMutableURLRequest
+      requestWithURL:[NSURL URLWithString:@"https://destination.url/"]];
+  [request setValue:@"https://referrer.url/"
+      forHTTPHeaderField:@"Referer"];
+
+  web::WebStatePolicyDecider::RequestInfo request_info(
+      ui::PageTransition::PAGE_TRANSITION_LINK,
+      /*target_frame_is_main=*/true,
+      /*target_frame_is_cross_origin=*/true,
+      /*target_window_is_cross_origin=*/false,
+      /*is_user_initiated=*/true,
+      /*user_tapped_recently=*/true);
+
+  reader_mode_tab_helper()->ReaderModeContentDidCancelRequest(nil, request,
+                                                              request_info);
+
+  // Verify that the host WebState's navigation manager loaded the request
+  // with web::ReferrerPolicyStrictOriginWhenCrossOrigin.
+  EXPECT_TRUE(navigation_manager->LoadURLWithParamsWasCalled());
+  web::NavigationManager::WebLoadParams load_params =
+      navigation_manager->GetLastLoadURLWithParams().value();
+  EXPECT_EQ(GURL("https://destination.url/"), load_params.url);
+  EXPECT_EQ(GURL("https://referrer.url/"), load_params.referrer.url);
+  EXPECT_EQ(web::ReferrerPolicyStrictOriginWhenCrossOrigin,
+            load_params.referrer.policy);
+}
+
 INSTANTIATE_TEST_SUITE_P(
     All,
     ReaderModeTabHelperWithEligibilityTest,
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
index e5f1c9d..e10a6a4 100644
--- a/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
+++ b/ios/chrome/browser/reader_mode/model/reader_mode_tab_helper_unittest.mm
@@ -991,6 +991,56 @@
   EXPECT_EQ(0u, infobar_manager->infobars().size());
 }
 
+// Tests that when Reader Mode cancels a request, the request is forwarded to
+// the navigation manager with the correct
+// ReferrerPolicyStrictOriginWhenCrossOrigin policy.
+TEST_F(ReaderModeTabHelperTest, ReaderModeContentDidCancelRequestForwarding) {
+  web_state()->WasShown();
+  GURL test_url("https://test.url/");
+  LoadWebpage(web_state(), test_url);
+  SetReaderModeState(web_state(), test_url,
+                     ReaderModeHeuristicResult::kReaderModeEligible, "Content");
+  WaitForPageLoadDelayAndRunUntilIdle();
+
+  // Activate Reader Mode.
+  reader_mode_tab_helper()->ActivateReader(
+      ReaderModeAccessPoint::kContextualChip);
+  WaitForAvailableReaderModeContentInWebState(web_state());
+
+  // Ensure the host tab navigation manager has not been called yet.
+  web::FakeNavigationManager* navigation_manager =
+      static_cast<web::FakeNavigationManager*>(
+          web_state()->GetNavigationManager());
+  ASSERT_FALSE(navigation_manager->LoadURLWithParamsWasCalled());
+
+  // Simulate a navigation cancellation with a referrer.
+  NSMutableURLRequest* request = [NSMutableURLRequest
+      requestWithURL:[NSURL URLWithString:@"https://destination.url/"]];
+  [request setValue:@"https://referrer.url/"
+      forHTTPHeaderField:@"Referer"];
+
+  web::WebStatePolicyDecider::RequestInfo request_info(
+      ui::PageTransition::PAGE_TRANSITION_LINK,
+      /*target_frame_is_main=*/true,
+      /*target_frame_is_cross_origin=*/true,
+      /*target_window_is_cross_origin=*/false,
+      /*is_user_initiated=*/true,
+      /*user_tapped_recently=*/true);
+
+  reader_mode_tab_helper()->ReaderModeContentDidCancelRequest(nil, request,
+                                                              request_info);
+
+  // Verify that the host WebState's navigation manager loaded the request
+  // with web::ReferrerPolicyStrictOriginWhenCrossOrigin.
+  EXPECT_TRUE(navigation_manager->LoadURLWithParamsWasCalled());
+  web::NavigationManager::WebLoadParams load_params =
+      navigation_manager->GetLastLoadURLWithParams().value();
+  EXPECT_EQ(GURL("https://destination.url/"), load_params.url);
+  EXPECT_EQ(GURL("https://referrer.url/"), load_params.referrer.url);
+  EXPECT_EQ(web::ReferrerPolicyStrictOriginWhenCrossOrigin,
+            load_params.referrer.policy);
+}
+
 INSTANTIATE_TEST_SUITE_P(
     All,
     ReaderModeTabHelperWithEligibilityTest,
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.