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 <[email protected]> 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 <[email protected]> Reviewed-by: Ari Chivukula <[email protected]> Reviewed-by: Bo Liu <[email protected]> Reviewed-by: Ryan Sturm <[email protected]> Reviewed-by: Kenichi Ishibashi <[email protected]> Reviewed-by: Dave Tapuska <[email protected]> Commit-Queue: Aldo Culquicondor <[email protected]> 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