0

Fix crash in DedicatedWorkerHostFactoryImpl

The crash occurs because the old code assumes that *every* context that
obtains storage access via the Storage Access API also has a matching
permission grant. This is not the case for A(B(A)) embedded contexts,
since there is no privacy boundary between the inner and outer A
documents.

Fixed: 409838513
Change-Id: I906411da80d91e38b5c7748d6dfcebb92c96a628
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6495132
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Auto-Submit: Chris Fredrickson <cfredric@chromium.org>
Commit-Queue: Chris Fredrickson <cfredric@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453291}
This commit is contained in:
Chris Fredrickson
2025-04-29 08:51:29 -07:00
committed by Chromium LUCI CQ
parent 9ab62833e4
commit 93cc2cb4df
2 changed files with 32 additions and 3 deletions
chrome/browser/storage_access_api
content/browser/worker_host

@ -1949,6 +1949,35 @@ IN_PROC_BROWSER_TEST_F(StorageAccessAPIBrowserTest,
"cross-site=b.test");
}
// Regression test for https://crbug.com/409838513.
IN_PROC_BROWSER_TEST_F(StorageAccessAPIBrowserTest,
DedicatedWorker_ABA_InheritsStorageAccessFromDocument) {
SetBlockThirdPartyCookies(true);
prompt_factory()->set_response_type(
permissions::PermissionRequestManager::DENY_ALL);
NavigateToPageWithFrame(kHostA);
NavigateFrameTo(kHostB, "/iframe.html");
NavigateNestedFrameTo(EchoCookiesURL(kHostA));
ASSERT_TRUE(
storage::test::RequestAndCheckStorageAccessForFrame(GetNestedFrame()));
ASSERT_TRUE(content::NavigateToURLFromRenderer(
GetNestedFrame(),
https_server().GetURL(
kHostA,
"/workers/fetch_from_worker.html?script=fetch_from_worker.js")));
ASSERT_TRUE(storage::test::HasStorageAccessForFrame(GetNestedFrame()));
// When the worker's parent document has storage access at the time the worker
// is created, the worker should inherit that access and be able to use it.
//
// This should work despite the fact that this is an ABA context, and
// therefore there is no explicit permission grant.
EXPECT_EQ(content::EvalJs(GetNestedFrame(),
"fetch_from_worker('/echoheader?cookie');"),
"cross-site=a.test");
}
IN_PROC_BROWSER_TEST_F(StorageAccessAPIBrowserTest,
WebsocketRequestsUseStorageAccessGrants) {
SetBlockThirdPartyCookies(true);

@ -12,6 +12,7 @@
#include "content/browser/devtools/devtools_throttle_handle.h"
#include "content/browser/devtools/worker_devtools_manager.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/storage_access/storage_access_handle.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/worker_host/dedicated_worker_host.h"
#include "content/browser/worker_host/dedicated_worker_service_impl.h"
@ -98,9 +99,8 @@ void DedicatedWorkerHostFactoryImpl::CreateWorkerHostAndStartScriptLoad(
RenderFrameHostImpl* ancestor_render_frame_host =
RenderFrameHostImpl::FromID(ancestor_render_frame_host_id_);
if (!ancestor_render_frame_host ||
ancestor_render_frame_host->GetPermissionStatus(
blink::PermissionType::STORAGE_ACCESS_GRANT) !=
blink::mojom::PermissionStatus::GRANTED) {
!StorageAccessHandle::DoesDocumentHaveStorageAccess(
ancestor_render_frame_host)) {
mojo::ReportBadMessage("DWH_STORAGE_ACCESS_NOT_GRANTED");
return;
}