Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partition Blob Registry by the top-level main document origin #7549

Merged
merged 1 commit into from
Aug 23, 2023

Conversation

sysrqb
Copy link
Contributor

@sysrqb sysrqb commented Dec 13, 2022

7f2ea8f

Partition Blob Registry by the top-level main document origin
https://bugs.webkit.org/show_bug.cgi?id=260035
rdar://problem/113705298

Reviewed by Alex Christensen and Sihui Liu.

Public blob URLs are only accessible from same-origin dcuments, but access is
not restricted by the top-level origin. This means that Blob URLs can be used
as a cross-origin tracking mechanism within iframes. In this patch we partition
public blob URLs within the Blob Registry by top-level origin. This
partitioning is controlled by a feature flag that is disabled by default.

I took a few approaches at solving this. The most difficult challenge was
finding a solution that allowed retrieving BlobData using a public blob URL
from WKWebView APIs. In that case, the relevant top document may not be
obvious, or may not exist. As a result, the design of this partitioning is more
like access control rather than adding another key into the hashmap.

Two alternative designs I considered include creating a second hashmap that is
keyed by <URL, SecurityOriginData> and we lookup the BlobData in that map if we
have a SecurityOriginData, otherwise we use the unpartitioned map. Or, we
create a new map from URL -> SecurityOriginData where we can lookup the
associated top origin SecurityOriginData if we don't already know it. However,
both of these options are more complex than the chosen implementation, and
neither of them seemed safer.

This change also enforces a noopener policy on new windows when the top origin
of the opener is cross-origin with the blob's security origin. This is a
mitigation that was discussed in the blob URL storage partitioning issue [0]
with cross-engine support, and that seemed reasonable to me.

[0] w3c/FileAPI#153

* LayoutTests/TestExpectations:
* LayoutTests/http/tests/local/blob/download-blob-from-iframe-expected.txt: Added.
* LayoutTests/http/tests/local/blob/download-blob-from-iframe.html: Added.
* LayoutTests/http/tests/local/blob/navigate-blob-expected.txt: Added.
* LayoutTests/http/tests/local/blob/navigate-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/broadcast-channel-proxy.html: Added.
* LayoutTests/http/tests/local/blob/resources/iframe-creating-or-downloading-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/iframe-for-creating-and-navigating-to-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/main-frame-with-iframe-creating-or-navigating-to-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/main-frame-with-iframe-downloading-blob.html: Added.
* LayoutTests/http/tests/security/blob-null-url-location-origin-expected.txt:
* LayoutTests/http/tests/security/blob-null-url-location-origin.html:
* LayoutTests/http/tests/security/cross-origin-blob-transfer-expected.txt: Added.
* LayoutTests/http/tests/security/cross-origin-blob-transfer.html: Added.
* LayoutTests/http/tests/security/resources/iframe-cross-origin-blob-transfer.html: Added.
* LayoutTests/http/tests/security/top-level-unique-origin2.https.html:
* LayoutTests/platform/gtk-wk2/http/tests/local/blob/download-blob-from-iframe-expected.txt: Added.
* LayoutTests/platform/mac-wk1/TestExpectations:
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WebCore/fileapi/BlobURL.cpp:
(WebCore::BlobURL::isInternalURL):
* Source/WebCore/fileapi/BlobURL.h:
* Source/WebCore/fileapi/ThreadableBlobRegistry.cpp:
(WebCore::ThreadableBlobRegistry::registerInternalFileBlobURL):
(WebCore::ThreadableBlobRegistry::registerInternalBlobURL):
(WebCore::ThreadableBlobRegistry::registerInternalBlobURLOptionallyFileBacked):
(WebCore::ThreadableBlobRegistry::registerInternalBlobURLForSlice):
(WebCore::isInternalBlobURL): Deleted.
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::createWindow):
* Source/WebCore/platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
(WebCore::BlobRegistryImpl::unregisterBlobURL):
(WebCore::BlobRegistryImpl::getBlobDataFromURL const):
(WebCore::BlobRegistryImpl::addBlobData):
(WebCore::BlobRegistryImpl::registerBlobURLHandle):
(WebCore::BlobRegistryImpl::unregisterBlobURLHandle):
* Source/WebCore/platform/network/BlobRegistryImpl.h:

Canonical link: https://commits.webkit.org/267172@main

4806ee0

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ›  gtk
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  πŸ§ͺ jsc βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ§ͺ api-gtk
βœ… πŸ›  πŸ§ͺ jsc-arm64 βœ… πŸ›  tv βœ… πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ›  jsc-armv7
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress βœ… πŸ§ͺ jsc-armv7-tests
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch βœ… πŸ›  jsc-mips
βœ… πŸ›  watch-sim βœ… πŸ§ͺ jsc-mips-tests

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Dec 13, 2022
@sysrqb sysrqb changed the title Isolate blob URLs P Jan 18, 2023
@sysrqb sysrqb changed the title P Partition Blob Registry by the top-level main frame Jan 24, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 10, 2023
@sysrqb sysrqb removed the merging-blocked Applied to prevent a change from being merged label Aug 10, 2023
@sysrqb sysrqb added the DOM For bugs specific to XML/HTML DOM elements (including parsing). label Aug 10, 2023
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 10, 2023
@sysrqb sysrqb removed the merging-blocked Applied to prevent a change from being merged label Aug 14, 2023
@sysrqb sysrqb marked this pull request as ready for review August 16, 2023 18:20
Copy link
Contributor

@szewai szewai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partitioning looks good to me; need @cdumez or @achristensen07 to review the changes for navigation.

Source/WebCore/platform/network/BlobRegistryImpl.h Outdated Show resolved Hide resolved
Source/WebCore/platform/network/BlobRegistryImpl.cpp Outdated Show resolved Hide resolved
Source/WebCore/platform/network/BlobRegistryImpl.cpp Outdated Show resolved Hide resolved
Source/WebCore/platform/network/BlobRegistryImpl.cpp Outdated Show resolved Hide resolved
Source/WebCore/platform/network/BlobRegistryImpl.cpp Outdated Show resolved Hide resolved
@sysrqb sysrqb requested a review from szewai August 21, 2023 22:16
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Aug 21, 2023
@sysrqb sysrqb removed the merging-blocked Applied to prevent a change from being merged label Aug 22, 2023
Copy link
Contributor

@szewai szewai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me

Source/WebCore/platform/network/BlobRegistryImpl.cpp Outdated Show resolved Hide resolved
Source/WebCore/platform/network/BlobRegistryImpl.cpp Outdated Show resolved Hide resolved
@sysrqb sysrqb added the merge-queue Applied to send a pull request to merge-queue label Aug 23, 2023
https://bugs.webkit.org/show_bug.cgi?id=260035
rdar://problem/113705298

Reviewed by Alex Christensen and Sihui Liu.

Public blob URLs are only accessible from same-origin dcuments, but access is
not restricted by the top-level origin. This means that Blob URLs can be used
as a cross-origin tracking mechanism within iframes. In this patch we partition
public blob URLs within the Blob Registry by top-level origin. This
partitioning is controlled by a feature flag that is disabled by default.

I took a few approaches at solving this. The most difficult challenge was
finding a solution that allowed retrieving BlobData using a public blob URL
from WKWebView APIs. In that case, the relevant top document may not be
obvious, or may not exist. As a result, the design of this partitioning is more
like access control rather than adding another key into the hashmap.

Two alternative designs I considered include creating a second hashmap that is
keyed by <URL, SecurityOriginData> and we lookup the BlobData in that map if we
have a SecurityOriginData, otherwise we use the unpartitioned map. Or, we
create a new map from URL -> SecurityOriginData where we can lookup the
associated top origin SecurityOriginData if we don't already know it. However,
both of these options are more complex than the chosen implementation, and
neither of them seemed safer.

This change also enforces a noopener policy on new windows when the top origin
of the opener is cross-origin with the blob's security origin. This is a
mitigation that was discussed in the blob URL storage partitioning issue [0]
with cross-engine support, and that seemed reasonable to me.

[0] w3c/FileAPI#153

* LayoutTests/TestExpectations:
* LayoutTests/http/tests/local/blob/download-blob-from-iframe-expected.txt: Added.
* LayoutTests/http/tests/local/blob/download-blob-from-iframe.html: Added.
* LayoutTests/http/tests/local/blob/navigate-blob-expected.txt: Added.
* LayoutTests/http/tests/local/blob/navigate-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/broadcast-channel-proxy.html: Added.
* LayoutTests/http/tests/local/blob/resources/iframe-creating-or-downloading-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/iframe-for-creating-and-navigating-to-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/main-frame-with-iframe-creating-or-navigating-to-blob.html: Added.
* LayoutTests/http/tests/local/blob/resources/main-frame-with-iframe-downloading-blob.html: Added.
* LayoutTests/http/tests/security/blob-null-url-location-origin-expected.txt:
* LayoutTests/http/tests/security/blob-null-url-location-origin.html:
* LayoutTests/http/tests/security/cross-origin-blob-transfer-expected.txt: Added.
* LayoutTests/http/tests/security/cross-origin-blob-transfer.html: Added.
* LayoutTests/http/tests/security/resources/iframe-cross-origin-blob-transfer.html: Added.
* LayoutTests/http/tests/security/top-level-unique-origin2.https.html:
* LayoutTests/platform/gtk-wk2/http/tests/local/blob/download-blob-from-iframe-expected.txt: Added.
* LayoutTests/platform/mac-wk1/TestExpectations:
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WebCore/fileapi/BlobURL.cpp:
(WebCore::BlobURL::isInternalURL):
* Source/WebCore/fileapi/BlobURL.h:
* Source/WebCore/fileapi/ThreadableBlobRegistry.cpp:
(WebCore::ThreadableBlobRegistry::registerInternalFileBlobURL):
(WebCore::ThreadableBlobRegistry::registerInternalBlobURL):
(WebCore::ThreadableBlobRegistry::registerInternalBlobURLOptionallyFileBacked):
(WebCore::ThreadableBlobRegistry::registerInternalBlobURLForSlice):
(WebCore::isInternalBlobURL): Deleted.
* Source/WebCore/loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadURL):
(WebCore::FrameLoader::loadPostRequest):
(WebCore::createWindow):
* Source/WebCore/platform/network/BlobRegistryImpl.cpp:
(WebCore::BlobRegistryImpl::registerBlobURLOptionallyFileBacked):
(WebCore::BlobRegistryImpl::unregisterBlobURL):
(WebCore::BlobRegistryImpl::getBlobDataFromURL const):
(WebCore::BlobRegistryImpl::addBlobData):
(WebCore::BlobRegistryImpl::registerBlobURLHandle):
(WebCore::BlobRegistryImpl::unregisterBlobURLHandle):
* Source/WebCore/platform/network/BlobRegistryImpl.h:

Canonical link: https://commits.webkit.org/267172@main
@webkit-commit-queue
Copy link
Collaborator

Committed 267172@main (7f2ea8f): https://commits.webkit.org/267172@main

Reviewed commits have been landed. Closing PR #7549 and removing active labels.

@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Aug 23, 2023
@webkit-commit-queue webkit-commit-queue merged commit 7f2ea8f into WebKit:main Aug 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DOM For bugs specific to XML/HTML DOM elements (including parsing).
Projects
None yet
6 participants