Chrome · Network
CVE-2026-14045
Logic Error in Network
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifandroid_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc |
modified | |
AwProxyingRestrictedCookieManagerTestandroid_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc |
modified |
Files Changed
android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.ccandroid_webview/browser/network_service/aw_proxying_restricted_cookie_manager.handroid_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
Patch
From 05514ce846dd58fef7544a4e64ddb1c1cabd8545 Mon Sep 17 00:00:00 2001
From: Aldo Culquicondor <acondor@chromium.org>
Date: Mon, 11 May 2026 15:27:33 -0700
Subject: [PATCH] Remove feature gates AsyncSetCookie and GetCookiesOnSet
Feature AsyncSetCookie was released.
Feature GetCookiesOnSet was abandoned.
Fixed: 497723649
Change-Id: Ib09becc6dd0dd8e4ba311e9e1f6ac7bac443a539
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7819154
Reviewed-by: Dominic Farolino <dom@chromium.org>
Reviewed-by: Ari Chivukula <arichiv@chromium.org>
Reviewed-by: Bo Liu <boliu@chromium.org>
Reviewed-by: Ryan Sturm <ryansturm@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1628861}
---
diff --git a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc
index d7b9d83..53626f9 100644
--- a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc
+++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc
@@ -189,17 +189,14 @@
const net::SiteForCookies& site_for_cookies,
const url::Origin& top_frame_origin,
net::StorageAccessApiStatus storage_access_api_status,
- bool get_version_shared_memory,
bool is_ad_tagged,
bool apply_devtools_overrides,
- const std::string& cookie,
- SetCookieFromStringCallback callback) {
+ const std::string& cookie) {
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
PrivacySetting cookieState = AllowCookies(url, site_for_cookies);
if (cookieState == PrivacySetting::kStateDisallowed) {
- std::move(callback).Run(/*response=*/nullptr);
return;
}
@@ -211,17 +208,9 @@
if (cookieState == PrivacySetting::kStateAllowed ||
(parsed_cookie.IsValid() && parsed_cookie.IsPartitioned() &&
parsed_cookie.IsSecure())) {
- // When using latched cookie policy, enable shared memory versioning.
- const bool use_shared_memory =
- base::FeatureList::IsEnabled(features::kWebViewLatchedCookiePolicy) &&
- get_version_shared_memory;
-
underlying_restricted_cookie_manager_->SetCookieFromString(
url, site_for_cookies, top_frame_origin, storage_access_api_status,
- use_shared_memory, is_ad_tagged, apply_devtools_overrides, cookie,
- std::move(callback));
- } else {
- std::move(callback).Run(/*response=*/nullptr);
+ is_ad_tagged, apply_devtools_overrides, cookie);
}
}
diff --git a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h
index fbe00f6..93c3ca5 100644
--- a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h
+++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h
@@ -84,11 +84,9 @@
const net::SiteForCookies& site_for_cookies,
const url::Origin& top_frame_origin,
net::StorageAccessApiStatus storage_access_api_status,
- bool get_version_shared_memory,
bool is_ad_tagged,
bool apply_devtools_overrides,
- const std::string& cookie,
- SetCookieFromStringCallback callback) override;
+ const std::string& cookie) override;
void GetCookiesString(const GURL& url,
const net::SiteForCookies& site_for_cookies,
diff --git a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
index 4a5bea4f..a30a2d1 100644
--- a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
+++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
@@ -83,14 +83,9 @@
const net::SiteForCookies& site_for_cookies,
const url::Origin& top_frame_origin,
net::StorageAccessApiStatus storage_access_api_status,
- bool get_version_shared_memory,
bool is_ad_tagged,
bool apply_devtools_overrides,
- const std::string& cookie,
- SetCookieFromStringCallback callback) override {
- last_set_cookie_shared_memory_param_ = get_version_shared_memory;
- std::move(callback).Run(nullptr);
- }
+ const std::string& cookie) override {}
void GetCookiesString(const GURL& url,
const net::SiteForCookies& site_for_cookies,
@@ -118,13 +113,9 @@
bool last_get_cookies_shared_memory_param() const {
return last_get_cookies_shared_memory_param_;
}
- bool last_set_cookie_shared_memory_param() const {
- return last_set_cookie_shared_memory_param_;
- }
private:
bool last_get_cookies_shared_memory_param_ = false;
- bool last_set_cookie_shared_memory_param_ = false;
};
class AwProxyingRestrictedCookieManagerTest : public testing::Test {
@@ -337,84 +328,5 @@
EXPECT_FALSE(mock_rcm.last_get_cookies_shared_memory_param());
}
-// Test: SetCookieFromString passes through shared memory flag when feature
-// enabled.
-TEST_F(AwProxyingRestrictedCookieManagerTest,
- SetCookieFromStringPassesSharedMemory_WhenFeatureEnabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kWebViewLatchedCookiePolicy);
-
- cookie_access_policy_.SetShouldAcceptCookies(true);
-
- MockRestrictedCookieManager mock_rcm;
- mojo::Receiver<network::mojom::RestrictedCookieManager> mock_receiver(
- &mock_rcm);
-
- mojo::Remote<network::mojom::RestrictedCookieManager> proxy_remote;
-
- CreateProxyOnIOThread(mock_receiver.BindNewPipeAndPassRemote(),
- proxy_remote.BindNewPipeAndPassReceiver());
-
- ASSERT_TRUE(
- base::test::RunUntil([&]() { return proxy_remote.is_connected(); }));
-
- base::RunLoop run_loop;
- proxy_remote->SetCookieFromString(
- GURL("https://example.com"),
- net::SiteForCookies::FromUrl(GURL("https://example.com")),
- url::Origin::Create(GURL("https://example.com")),
- net::StorageAccessApiStatus::kNone,
- /*get_version_shared_memory=*/true, // Request shared memory.
- /*is_ad_tagged=*/false,
- /*apply_devtools_overrides=*/false, "testcookie=value",
- base::BindOnce(
- [](base::RunLoop* run_loop,
- network::mojom::CookiesResponsePtr response) { run_loop->Quit(); },
- &run_loop));
- run_loop.Run();
-
- // Verify shared memory flag was passed through.
- EXPECT_TRUE(mock_rcm.last_set_cookie_shared_memory_param());
-}
-
-// Test: SetCookieFromString blocks shared memory flag when feature disabled.
-TEST_F(AwProxyingRestrictedCookieManagerTest,
- SetCookieFromStringBlocksSharedMemory_WhenFeatureDisabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndDisableFeature(features::kWebViewLatchedCookiePolicy);
-
- cookie_access_policy_.SetShouldAcceptCookies(true);
-
- MockRestrictedCookieManager mock_rcm;
- mojo::Receiver<network::mojom::RestrictedCookieManager> mock_receiver(
- &mock_rcm);
-
- mojo::Remote<network::mojom::RestrictedCookieManager> proxy_remote;
-
- CreateProxyOnIOThread(mock_receiver.BindNewPipeAndPassRemote(),
- proxy_remote.BindNewPipeAndPassReceiver());
-
- ASSERT_TRUE(
- base::test::RunUntil([&]() { return proxy_remote.is_connected(); }));
-
- base::RunLoop run_loop;
- proxy_remote->SetCookieFromString(
- GURL("https://example.com"),
- net::SiteForCookies::FromUrl(GURL("https://example.com")),
- url::Origin::Create(GURL("https://example.com")),
- net::StorageAccessApiStatus::kNone,
- /*get_version_shared_memory=*/true, // Request shared memory.
- /*is_ad_tagged=*/false,
- /*apply_devtools_overrides=*/false, "testcookie=value",
- base::BindOnce(
- [](base::RunLoop* run_loop,
- network::mojom::CookiesResponsePtr response) { run_loop->Quit(); },
- &run_loop));
- run_loop.Run();
-
- // Verify shared memory flag was blocked.
- EXPECT_FALSE(mock_rcm.last_set_cookie_shared_memory_param());
-}
-
} // namespace
} // namespace android_webview
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
index 4a5bea4f..a30a2d1 100644
--- a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
+++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager_unittest.cc
@@ -83,14 +83,9 @@
const net::SiteForCookies& site_for_cookies,
const url::Origin& top_frame_origin,
net::StorageAccessApiStatus storage_access_api_status,
- bool get_version_shared_memory,
bool is_ad_tagged,
bool apply_devtools_overrides,
- const std::string& cookie,
- SetCookieFromStringCallback callback) override {
- last_set_cookie_shared_memory_param_ = get_version_shared_memory;
- std::move(callback).Run(nullptr);
- }
+ const std::string& cookie) override {}
void GetCookiesString(const GURL& url,
const net::SiteForCookies& site_for_cookies,
@@ -118,13 +113,9 @@
bool last_get_cookies_shared_memory_param() const {
return last_get_cookies_shared_memory_param_;
}
- bool last_set_cookie_shared_memory_param() const {
- return last_set_cookie_shared_memory_param_;
- }
private:
bool last_get_cookies_shared_memory_param_ = false;
- bool last_set_cookie_shared_memory_param_ = false;
};
class AwProxyingRestrictedCookieManagerTest : public testing::Test {
@@ -337,84 +328,5 @@
EXPECT_FALSE(mock_rcm.last_get_cookies_shared_memory_param());
}
-// Test: SetCookieFromString passes through shared memory flag when feature
-// enabled.
-TEST_F(AwProxyingRestrictedCookieManagerTest,
- SetCookieFromStringPassesSharedMemory_WhenFeatureEnabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(features::kWebViewLatchedCookiePolicy);
-
- cookie_access_policy_.SetShouldAcceptCookies(true);
-
- MockRestrictedCookieManager mock_rcm;
- mojo::Receiver<network::mojom::RestrictedCookieManager> mock_receiver(
- &mock_rcm);
-
- mojo::Remote<network::mojom::RestrictedCookieManager> proxy_remote;
-
- CreateProxyOnIOThread(mock_receiver.BindNewPipeAndPassRemote(),
- proxy_remote.BindNewPipeAndPassReceiver());
-
- ASSERT_TRUE(
- base::test::RunUntil([&]() { return proxy_remote.is_connected(); }));
-
- base::RunLoop run_loop;
- proxy_remote->SetCookieFromString(
- GURL("https://example.com"),
- net::SiteForCookies::FromUrl(GURL("https://example.com")),
- url::Origin::Create(GURL("https://example.com")),
- net::StorageAccessApiStatus::kNone,
- /*get_version_shared_memory=*/true, // Request shared memory.
- /*is_ad_tagged=*/false,
- /*apply_devtools_overrides=*/false, "testcookie=value",
- base::BindOnce(
- [](base::RunLoop* run_loop,
- network::mojom::CookiesResponsePtr response) { run_loop->Quit(); },
- &run_loop));
- run_loop.Run();
-
- // Verify shared memory flag was passed through.
- EXPECT_TRUE(mock_rcm.last_set_cookie_shared_memory_param());
-}
-
-// Test: SetCookieFromString blocks shared memory flag when feature disabled.
-TEST_F(AwProxyingRestrictedCookieManagerTest,
- SetCookieFromStringBlocksSharedMemory_WhenFeatureDisabled) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndDisableFeature(features::kWebViewLatchedCookiePolicy);
-
- cookie_access_policy_.SetShouldAcceptCookies(true);
-
- MockRestrictedCookieManager mock_rcm;
- mojo::Receiver<network::mojom::RestrictedCookieManager> mock_receiver(
- &mock_rcm);
-
- mojo::Remote<network::mojom::RestrictedCookieManager> proxy_remote;
-
- CreateProxyOnIOThread(mock_receiver.BindNewPipeAndPassRemote(),
- proxy_remote.BindNewPipeAndPassReceiver());
-
- ASSERT_TRUE(
- base::test::RunUntil([&]() { return proxy_remote.is_connected(); }));
-
- base::RunLoop run_loop;
- proxy_remote->SetCookieFromString(
- GURL("https://example.com"),
- net::SiteForCookies::FromUrl(GURL("https://example.com")),
- url::Origin::Create(GURL("https://example.com")),
- net::StorageAccessApiStatus::kNone,
- /*get_version_shared_memory=*/true, // Request shared memory.
- /*is_ad_tagged=*/false,
- /*apply_devtools_overrides=*/false, "testcookie=value",
- base::BindOnce(
- [](base::RunLoop* run_loop,
- network::mojom::CookiesResponsePtr response) { run_loop->Quit(); },
- &run_loop));
- run_loop.Run();
-
- // Verify shared memory flag was blocked.
- EXPECT_FALSE(mock_rcm.last_set_cookie_shared_memory_param());
-}
-
} // namespace
} // namespace android_webview
diff --git a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
index 92743fe..371dc12 100644
--- a/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
+++ b/chrome/browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc
@@ -505,12 +505,10 @@
observer.Wait();
NavigateToUntrackedUrl();
- const int expected_reads =
- base::FeatureList::IsEnabled(network::features::kGetCookiesOnSet) ? 1 : 0;
- histogram_tester.ExpectUniqueSample(kReadCookieHistogram, expected_reads, 1);
+ histogram_tester.ExpectUniqueSample(kReadCookieHistogram, 0, 1);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
- blink::mojom::WebFeature::kThirdPartyCookieRead, expected_reads);
+ blink::mojom::WebFeature::kThirdPartyCookieRead, 0);
histogram_tester.ExpectBucketCount(
"Blink.UseCounter.Features",
blink::mojom::WebFeature::kThirdPartyCookieWrite, 1);
diff --git a/content/browser/btm/btm_bounce_detector_browsertest.cc b/content/browser/btm/btm_bounce_detector_browsertest.cc
index 767dc97..e8a94f41 100644
--- a/content/browser/btm/btm_bounce_detector_browsertest.cc
+++ b/content/browser/btm/btm_bounce_detector_browsertest.cc
@@ -628,15 +628,9 @@
GetActiveWebContents(), primary_main_frame_final_url));
CloseTab(GetActiveWebContents());
- std::string access_type =
- base::FeatureList::IsEnabled(network::features::kGetCookiesOnSet)
- ? "ReadWrite"
- : "Write";
EXPECT_THAT(redirects,
- ElementsAre(base::StringPrintf(
- "[1/1] blank -> a.test/page_with_blank_iframe.html "
- "(%s) -> d.test/title1.html",
- access_type)));
+ ElementsAre("[1/1] blank -> a.test/page_with_blank_iframe.html "
+ "(Write) -> d.test/title1.html"));
}
IN_PROC_BROWSER_TEST_F(BtmBounceDetectorBrowserTest,
@@ -775,15 +769,9 @@
GetActiveWebContents(), primary_main_frame_final_url));
CloseTab(GetActiveWebContents());
- std::string access_type =
- base::FeatureList::IsEnabled(network::features::kGetCookiesOnSet)
- ? "ReadWrite"
- : "Write";
EXPECT_THAT(redirects,
- ElementsAre(base::StringPrintf(
- "[1/1] blank -> a.test/page_with_blank_iframe.html "
- "(%s) -> d.test/title1.html",
- access_type)));
+ ElementsAre("[1/1] blank -> a.test/page_with_blank_iframe.html "
+ "(Write) -> d.test/title1.html"));
}
IN_PROC_BROWSER_TEST_F(BtmBounceDetectorBrowserTest,
@@ -1993,11 +1981,6 @@
"WebAuthnAssertionRequestSucceeded(b.test/title1.html)",
"DidStartNavigation(d.test/title1.html)",
"DidFinishNavigation(d.test/title1.html)"};
- if (base::FeatureList::IsEnabled(network::features::kGetCookiesOnSet)) {
- expected_log.insert(
- expected_log.begin() + 5,
- "OnCookiesAccessed(RenderFrameHost, Read: b.test/title1.html)");
- }
EXPECT_THAT(logger->log(), testing::ContainerEq(expected_log));
diff --git a/content/browser/renderer_host/cookie_browsertest.cc b/content/browser/renderer_host/cookie_browsertest.cc
index 3098457..015c8a1d 100644
--- a/content/browser/renderer_host/cookie_browsertest.cc
+++ b/content/browser/renderer_host/cookie_browsertest.cc
@@ -54,7 +54,6 @@
#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features_generated.h"
#include "url/gurl.h"
using testing::IsEmpty;
@@ -161,16 +160,10 @@
} // namespace
-class CookieBrowserTest
- : public ContentBrowserTest,
- public ::testing::WithParamInterface<std::tuple<bool, bool>> {
+class CookieBrowserTest : public ContentBrowserTest {
public:
CookieBrowserTest()
- : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {
- scoped_feature_list_.InitWithFeatureStates(
- {{network::features::kGetCookiesOnSet, GetCookiesOnSetEnabled()},
- {blink::features::kAsyncSetCookie, AsyncSetCookieEnabled()}});
- }
+ : https_server_(net::test_server::EmbeddedTestServer::TYPE_HTTPS) {}
~CookieBrowserTest() override = default;
protected:
@@ -188,29 +181,12 @@
ASSERT_TRUE(https_server_.Start());
}
- bool GetCookiesOnSetEnabled() { return std::get<0>(GetParam()); }
-
- bool AsyncSetCookieEnabled() { return std::get<1>(GetParam()); }
-
net::test_server::EmbeddedTestServer https_server_;
- base::test::ScopedFeatureList scoped_feature_list_;
};
-INSTANTIATE_TEST_SUITE_P(
- ,
- CookieBrowserTest,
- testing::Combine(testing::Bool(), testing::Bool()),
- [](const testing::TestParamInfo<std::tuple<bool, bool>>& info) {
- std::string name =
- std::get<0>(info.param) ? "GetOnSetEnabled" : "GetOnSetDisabled";
- name += "_";
- name += std::get<1>(info.param) ? "Async" : "Sync";
- return name;
- });
-
// Exercises basic cookie operations via javascript, including an http page
// interacting with secure cookies.
-IN_PROC_BROWSER_TEST_P(CookieBrowserTest, Cookies) {
+IN_PROC_BROWSER_TEST_F(CookieBrowserTest, Cookies) {
SetupCrossSiteRedirector(embedded_test_server());
ASSERT_TRUE(embedded_test_server()->Start());
@@ -291,7 +267,7 @@
}
// Ensure "priority" cookie option is settable via document.cookie.
-IN_PROC_BROWSER_TEST_P(CookieBrowserTest, CookiePriority) {
+IN_PROC_BROWSER_TEST_F(CookieBrowserTest, CookiePriority) {
ASSERT_TRUE(embedded_test_server()->Start());
struct {
@@ -306,10 +282,15 @@
GURL url = embedded_test_server()->GetURL("/set_document_cookie.html?" +
test_case.param);
EXPECT_TRUE(NavigateToURL(shell(), url));
+ // Ensure that the RestrictedCookieManager processed the SetCookieFromString
+ // IPCs by reading document.cookie from the renderer.
+ EXPECT_EQ("name=value",
+ GetCookieFromJS(shell()->web_contents()->GetPrimaryMainFrame()));
+
std::vector<net::CanonicalCookie> cookies =
GetCanonicalCookies(shell()->web_contents()->GetBrowserContext(), url);
- EXPECT_EQ(1u, cookies.size());
+ ASSERT_EQ(1u, cookies.size());
EXPECT_EQ("name", cookies[0].Name());
EXPECT_EQ("value", cookies[0].Value());
EXPECT_EQ(test_case.priority, cookies[0].Priority());
@@ -318,7 +299,7 @@
// SameSite cookies (that aren't marked as http-only) should be available to
// JavaScript.
-IN_PROC_BROWSER_TEST_P(CookieBrowserTest, SameSiteCookies) {
+IN_PROC_BROWSER_TEST_F(CookieBrowserTest, SameSiteCookies) {
// Must use HTTPS because SameSite=None cookies must be Secure.
// The server sets eight cookies on 'a.test' and on 'b.test', then loads
@@ -372,7 +353,7 @@
// Prefixed cookies (that aren't marked as http-only) should be available to
// JavaScript.
-IN_PROC_BROWSER_TEST_P(CookieBrowserTest, PrefixedCookies_Read) {
+IN_PROC_BROWSER_TEST_F(CookieBrowserTest, PrefixedCookies_Read) {
// Must use HTTPS because prefixed cookies must be Secure.
ASSERT_TRUE(SetCookie(shell()->web_contents()->GetBrowserContext(),
@@ -393,7 +374,7 @@
Key("__Host-cookie"), Key("__Secure-cookie"))));
}
-IN_PROC_BROWSER_TEST_P(CookieBrowserTest, PrefixedCookies_Read_Insecure) {
... (truncated)
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.
References
On This Page