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 --- a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h +++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h @@ -14,6 +14,7 @@ #include "content/public/browser/global_routing_id.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/network_delegate.h" +#include "net/cookies/site_for_cookies.h" #include "net/storage_access_api/status.h" #include "services/network/public/mojom/restricted_cookie_manager.mojom.h" @@ -42,6 +43,7 @@ class AwProxyingRestrictedCookieManager bool is_service_worker, int process_id, int frame_id, + const net::SiteForCookies& site_for_cookies, mojo::PendingReceiver receiver, AwCookieAccessPolicy* aw_cookie_access_policy); @@ -119,6 +121,7 @@ class AwProxyingRestrictedCookieManager bool is_service_worker, const std::optional& global_frame_token, + const net::SiteForCookies& site_for_cookies, AwCookieAccessPolicy* cookie_access_policy); static void CreateAndBindOnIoThread( @@ -127,6 +130,7 @@ class AwProxyingRestrictedCookieManager bool is_service_worker, const std::optional& global_frame_token, + const net::SiteForCookies& site_for_cookies, mojo::PendingReceiver receiver, AwCookieAccessPolicy* cookie_access_policy); @@ -134,6 +138,10 @@ class AwProxyingRestrictedCookieManager underlying_restricted_cookie_manager_; bool is_service_worker_; std::optional global_frame_token_; + // Trusted site_for_cookies captured from the browser-side IsolationInfo at + // bind time. Used in place of the renderer-supplied Mojo parameter when + // evaluating the per-WebView third-party-cookie policy. + const net::SiteForCookies bound_site_for_cookies_; raw_ref cookie_access_policy_; 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 --- a/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc +++ b/android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.cc @@ -78,6 +78,7 @@ void AwProxyingRestrictedCookieManager::CreateAndBind( bool is_service_worker, int process_id, int frame_id, + const net::SiteForCookies& site_for_cookies, mojo::PendingReceiver receiver, AwCookieAccessPolicy* aw_cookie_access_policy) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -94,7 +95,7 @@ void AwProxyingRestrictedCookieManager::CreateAndBind( base::BindOnce( &AwProxyingRestrictedCookieManager::CreateAndBindOnIoThread, std::move(underlying_rcm), is_service_worker, frame_token, - std::move(receiver), aw_cookie_access_policy)); + site_for_cookies, std::move(receiver), aw_cookie_access_policy)); } AwProxyingRestrictedCookieManager::~AwProxyingRestrictedCookieManager() { @@ -282,11 +283,13 @@ AwProxyingRestrictedCookieManager::AwProxyingRestrictedCookieManager( bool is_service_worker, const std::optional& global_frame_token, + const net::SiteForCookies& site_for_cookies, AwCookieAccessPolicy* cookie_access_policy) : underlying_restricted_cookie_manager_( std::move(underlying_restricted_cookie_manager)), is_service_worker_(is_service_worker), global_frame_token_(global_frame_token), + bound_site_for_cookies_(site_for_cookies), cookie_access_policy_(*cookie_access_policy) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); @@ -307,18 +310,25 @@ void AwProxyingRestrictedCookieManager::CreateAndBindOnIoThread( bool is_service_worker, const std::optional& global_frame_token, + const net::SiteForCookies& site_for_cookies, mojo::PendingReceiver receiver, AwCookieAccessPolicy* cookie_access_policy) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); auto wrapper = base::WrapUnique(new AwProxyingRestrictedCookieManager( std::move(underlying_rcm), is_service_worker, global_frame_token, - cookie_access_policy)); + site_for_cookies, cookie_access_policy)); mojo::MakeSelfOwnedReceiver(std::move(wrapper), std::move(receiver)); } PrivacySetting AwProxyingRestrictedCookieManager::AllowCookies( const GURL& url, const net::SiteForCookies& site_for_cookies) const { + // SECURITY: ignore the renderer-supplied `site_for_cookies` and use the + // trusted value captured from IsolationInfo at bind time. A compromised + // renderer can spoof the Mojo parameter to make a cross-site request look + // first-party and bypass setAcceptThirdPartyCookies(false). + const net::SiteForCookies& trusted_sfc = bound_site_for_cookies_; // When feature is enabled, use latched cookie policy state captured at // construction time. This enables shared memory cookie versioning. if (base::FeatureList::IsEnabled(features::kWebViewLatchedCookiePolicy)) { @@ -336,7 +346,7 @@ PrivacySetting AwProxyingRestrictedCookieManager::AllowCookies( return latched_accept_cookies_ ? PrivacySetting::kStateAllowed : PrivacySetting::kStateDisallowed; } - return AwCookieAccessPolicy::CanAccessCookies(url, site_for_cookies, + return AwCookieAccessPolicy::CanAccessCookies(url, trusted_sfc, latched_accept_cookies_, latched_accept_third_party_); } @@ -349,7 +359,7 @@ PrivacySetting AwProxyingRestrictedCookieManager::AllowCookies( ? PrivacySetting::kStateAllowed : PrivacySetting::kStateDisallowed; } else { - return cookie_access_policy_->AllowCookies(url, site_for_cookies, + return cookie_access_policy_->AllowCookies(url, trusted_sfc, global_frame_token_); } } diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc @@ -1295,7 +1295,8 @@ bool AwContentBrowserClient::WillCreateRestrictedCookieManager( AwProxyingRestrictedCookieManager::CreateAndBind( std::move(target_rcm_remote), is_service_worker, process_id, routing_id, - std::move(orig_receiver), aw_cookie_access_policy); + isolation_info.site_for_cookies(), std::move(orig_receiver), + aw_cookie_access_policy); return false; // only made a proxy, still need the actual impl to be made. }