Files
cromite/build/patches/Partition-blobs-by-top-frame-URL.patch
T

250 lines
11 KiB
Diff

From: uazo <uazo@users.noreply.github.com>
Date: Tue, 20 Sep 2022 07:20:01 +0000
Subject: Partition blobs by top frame URL
Verifies that the blob was created with the same top frame URL
or, if not defined, by the same agent cluster.
Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
---
.../Partition-blobs-by-top-frame-URL.inc | 1 +
storage/browser/blob/blob_url_store_impl.cc | 36 ++++++++++++++++++-
storage/browser/blob/blob_url_store_impl.h | 11 ++++++
storage/browser/blob/features.cc | 1 +
.../public/mojom/blob/blob_url_store.mojom | 12 +++++--
.../core/fileapi/public_url_manager.cc | 18 ++++++++++
6 files changed, 75 insertions(+), 4 deletions(-)
create mode 100644 cromite_flags/third_party/blink/common/features_cc/Partition-blobs-by-top-frame-URL.inc
diff --git a/cromite_flags/third_party/blink/common/features_cc/Partition-blobs-by-top-frame-URL.inc b/cromite_flags/third_party/blink/common/features_cc/Partition-blobs-by-top-frame-URL.inc
new file mode 100644
--- /dev/null
+++ b/cromite_flags/third_party/blink/common/features_cc/Partition-blobs-by-top-frame-URL.inc
@@ -0,0 +1 @@
+SET_CROMITE_FEATURE_ENABLED(kEnforceNoopenerOnBlobURLNavigation);
diff --git a/storage/browser/blob/blob_url_store_impl.cc b/storage/browser/blob/blob_url_store_impl.cc
--- a/storage/browser/blob/blob_url_store_impl.cc
+++ b/storage/browser/blob/blob_url_store_impl.cc
@@ -83,6 +83,20 @@ BlobURLStoreImpl::~BlobURLStoreImpl() {
}
}
+bool BlobURLStoreImpl::IsSamePartition(
+ const GURL& blob_url,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site) {
+ const std::optional<net::SchemefulSite>& top_level_site =
+ registry_->GetUnsafeTopLevelSite(blob_url);
+ if (top_level_site.has_value())
+ return top_level_site == unsafe_top_level_site;
+
+ std::optional<base::UnguessableToken> agent_cluster_id =
+ registry_->GetUnsafeAgentClusterID(blob_url);
+ return agent_cluster_id == unsafe_agent_cluster_id;
+}
+
void BlobURLStoreImpl::Register(
mojo::PendingRemote<blink::mojom::Blob> blob,
const GURL& url,
@@ -117,6 +131,8 @@ void BlobURLStoreImpl::Revoke(const GURL& url) {
void BlobURLStoreImpl::ResolveAsURLLoaderFactory(
const GURL& url,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site,
ResolveAsURLLoaderFactoryCallback callback) {
if (!registry_) {
BlobURLLoaderFactory::Create(mojo::NullRemote(), url, std::move(receiver));
@@ -132,6 +148,12 @@ void BlobURLStoreImpl::ResolveAsURLLoaderFactory(
return;
}
+ if (!IsSamePartition(url, unsafe_agent_cluster_id, unsafe_top_level_site)) {
+ BlobURLLoaderFactory::Create(mojo::NullRemote(), url, std::move(receiver));
+ std::move(callback).Run(std::nullopt, std::nullopt);
+ return;
+ }
+
BlobURLLoaderFactory::Create(registry_->GetBlobFromUrl(url), url,
std::move(receiver));
// When a fragment URL is present, registry_->GetUnsafeAgentClusterID(url) and
@@ -145,11 +167,17 @@ void BlobURLStoreImpl::ResolveAsURLLoaderFactory(
void BlobURLStoreImpl::ResolveForNavigation(
const GURL& url,
mojo::PendingReceiver<blink::mojom::BlobURLToken> token,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site,
ResolveForNavigationCallback callback) {
if (!registry_) {
std::move(callback).Run(std::nullopt);
return;
}
+ if (!IsSamePartition(url, unsafe_agent_cluster_id, unsafe_top_level_site)) {
+ std::move(callback).Run(std::nullopt);
+ return;
+ }
mojo::PendingRemote<blink::mojom::Blob> blob = registry_->GetBlobFromUrl(url);
if (!blob) {
std::move(callback).Run(std::nullopt);
@@ -162,11 +190,17 @@ void BlobURLStoreImpl::ResolveForNavigation(
void BlobURLStoreImpl::ResolveForWorkerScriptFetch(
const GURL& url,
mojo::PendingReceiver<blink::mojom::BlobURLToken> token,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site,
ResolveForNavigationCallback callback) {
if (!registry_) {
std::move(callback).Run(std::nullopt);
return;
}
+ if (!IsSamePartition(url, unsafe_agent_cluster_id, unsafe_top_level_site)) {
+ std::move(callback).Run(std::nullopt);
+ return;
+ }
if (base::FeatureList::IsEnabled(
features::kBlockCrossPartitionBlobUrlFetching) &&
!registry_->IsUrlMapped(BlobUrlUtils::ClearUrlFragment(url),
@@ -175,7 +209,7 @@ void BlobURLStoreImpl::ResolveForWorkerScriptFetch(
return;
}
- ResolveForNavigation(url, std::move(token), std::move(callback));
+ ResolveForNavigation(url, std::move(token), unsafe_agent_cluster_id, unsafe_top_level_site, std::move(callback));
}
bool BlobURLStoreImpl::BlobUrlIsValid(const GURL& url,
diff --git a/storage/browser/blob/blob_url_store_impl.h b/storage/browser/blob/blob_url_store_impl.h
--- a/storage/browser/blob/blob_url_store_impl.h
+++ b/storage/browser/blob/blob_url_store_impl.h
@@ -48,14 +48,20 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLStoreImpl
void ResolveAsURLLoaderFactory(
const GURL& url,
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site,
ResolveAsURLLoaderFactoryCallback callback) override;
void ResolveForNavigation(
const GURL& url,
mojo::PendingReceiver<blink::mojom::BlobURLToken> token,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site,
ResolveForNavigationCallback callback) override;
void ResolveForWorkerScriptFetch(
const GURL& url,
mojo::PendingReceiver<blink::mojom::BlobURLToken> token,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site,
ResolveForNavigationCallback callback) override;
private:
@@ -65,6 +71,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLStoreImpl
// `Revoke()`.
bool BlobUrlIsValid(const GURL& url, const char* method) const;
+ bool IsSamePartition(
+ const GURL& blob_url,
+ const base::UnguessableToken& unsafe_agent_cluster_id,
+ const std::optional<net::SchemefulSite>& unsafe_top_level_site);
+
const blink::StorageKey storage_key_;
// The origin used by the worker/document associated with this BlobURLStore on
// the renderer side. This will almost always be the same as `storage_key_`'s
diff --git a/storage/browser/blob/features.cc b/storage/browser/blob/features.cc
--- a/storage/browser/blob/features.cc
+++ b/storage/browser/blob/features.cc
@@ -10,6 +10,7 @@ namespace features {
BASE_FEATURE(kBlockCrossPartitionBlobUrlFetching,
"BlockCrossPartitionBlobUrlFetching",
base::FEATURE_DISABLED_BY_DEFAULT);
+SET_CROMITE_FEATURE_ENABLED(kBlockCrossPartitionBlobUrlFetching);
// Please keep features in alphabetical order.
diff --git a/third_party/blink/public/mojom/blob/blob_url_store.mojom b/third_party/blink/public/mojom/blob/blob_url_store.mojom
--- a/third_party/blink/public/mojom/blob/blob_url_store.mojom
+++ b/third_party/blink/public/mojom/blob/blob_url_store.mojom
@@ -37,7 +37,9 @@ interface BlobURLStore {
// both the blob URL and all other references to the blob have been dropped.
ResolveAsURLLoaderFactory(
url.mojom.Url url,
- pending_receiver<network.mojom.URLLoaderFactory> factory) => (
+ pending_receiver<network.mojom.URLLoaderFactory> factory,
+ mojo_base.mojom.UnguessableToken unsafe_agent_cluster_id,
+ network.mojom.SchemefulSite? unsafe_top_level_site) => (
// TODO(https://crbug.com/1224926): Remove these once experiment is over.
mojo_base.mojom.UnguessableToken? unsafe_agent_cluster_id,
network.mojom.SchemefulSite? unsafe_top_level_site);
@@ -47,7 +49,9 @@ interface BlobURLStore {
// refer to, even after the URL is revoked.
// As long as the token is alive, the resolved blob will also be kept alive.
ResolveForNavigation(url.mojom.Url url,
- pending_receiver<BlobURLToken> token) => (
+ pending_receiver<BlobURLToken> token,
+ mojo_base.mojom.UnguessableToken unsafe_agent_cluster_id,
+ network.mojom.SchemefulSite? unsafe_top_level_site) => (
// TODO(https://crbug.com/1224926): Remove this once experiment is over.
mojo_base.mojom.UnguessableToken? unsafe_agent_cluster_id);
@@ -58,7 +62,9 @@ interface BlobURLStore {
// currently intended for use when fetching a dedicated / shared worker
// script.
ResolveForWorkerScriptFetch(url.mojom.Url url,
- pending_receiver<BlobURLToken> token) => (
+ pending_receiver<BlobURLToken> token,
+ mojo_base.mojom.UnguessableToken unsafe_agent_cluster_id,
+ network.mojom.SchemefulSite? unsafe_top_level_site) => (
// TODO(https://crbug.com/1224926): Remove this once experiment is over.
mojo_base.mojom.UnguessableToken? unsafe_agent_cluster_id);
};
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.cc b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
--- a/third_party/blink/renderer/core/fileapi/public_url_manager.cc
+++ b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
@@ -63,6 +63,21 @@ static void RemoveFromNullOriginMapIfNecessary(const KURL& blob_url) {
BlobURLNullOriginMap::GetInstance()->Remove(blob_url);
}
+static std::optional<BlinkSchemefulSite> GetInsecureTopLevelSite(
+ ExecutionContext* execution_context) {
+ std::optional<BlinkSchemefulSite> top_level_site;
+ if (execution_context->IsWindow()) {
+ auto* window = To<LocalDOMWindow>(execution_context);
+ if (window->top() && window->top()->GetFrame()) {
+ top_level_site = BlinkSchemefulSite(window->top()
+ ->GetFrame()
+ ->GetSecurityContext()
+ ->GetSecurityOrigin());
+ }
+ }
+ return top_level_site;
+}
+
} // namespace
PublicURLManager::PublicURLManager(ExecutionContext* execution_context)
@@ -269,6 +284,7 @@ void PublicURLManager::Resolve(
GetBlobURLStore().ResolveAsURLLoaderFactory(
url, std::move(factory_receiver),
+ GetExecutionContext()->GetAgentClusterID(), GetInsecureTopLevelSite(GetExecutionContext()),
WTF::BindOnce(metrics_callback, WrapPersistent(GetExecutionContext())));
}
@@ -292,6 +308,7 @@ void PublicURLManager::Resolve(
GetBlobURLStore().ResolveForNavigation(
url, std::move(token_receiver),
+ GetExecutionContext()->GetAgentClusterID(), GetInsecureTopLevelSite(GetExecutionContext()),
WTF::BindOnce(metrics_callback, WrapPersistent(GetExecutionContext())));
}
@@ -318,6 +335,7 @@ void PublicURLManager::ResolveForWorkerScriptFetch(
GetBlobURLStore().ResolveForWorkerScriptFetch(
url, std::move(token_receiver),
+ GetExecutionContext()->GetAgentClusterID(), GetInsecureTopLevelSite(GetExecutionContext()),
WTF::BindOnce(metrics_callback, WrapPersistent(GetExecutionContext())));
}
--