You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@bakulf was thinking that we could restrict blob URL lookup to the agent cluster (in addition to origin, that is). The one tweak I would suggest to that is that navigating a top-level browsing context (including a noopener one) to a blob URL still ought to work.
Concretely, this would mean that if you have https://example.com/ open twice, in separate browsing context groups, any blob URLs they mint cannot be used by the other.
The one gotcha with the tweak I suggested is that the other could observe existence through a popup then. Now that's an attack that's unlikely to yield anything useful in practice, but we could break that too by forcing noopener or a version of COOP that never matches (and thus always creates a new browsing context group).
We suspect this to be web-compatible and are happy to try it out in Firefox.
Limiting it like that doesn't seem too crazy to me, although I'm not entirely sure I understand the attack/threat model that defends against.
A blob URL can only be resolved when the page that created it is still alive, and when the page trying to fetch it is same origin with the original page. If that is the case, you might as well just BroadcastChannel to talk to the original page, rather than jumping through hoops with blob URLs?
Of course if storage partitioning blocks BroadcastChannel because of different top-level URLs things would be different, but in that case wouldn't it make more sense to partition blob URLs the same way as other communication mechanisms, rather than having them be partitioned even more?
Having said all that, for MediaSource blob URLs chrome already limits them to their agent cluster. And scoping all blob URLs to their agent cluster certainly would make the implementation a whole lot simpler (well, the top-level navigation case would still be tricky). So as an implementer agent cluster seems reasonable, as a spec editor I question if that is the right scoping level.
The keying for storage seems like it will end up being dynamic (i.e., storage access). I think if we can avoid things being dynamically keyed that's preferable.
To expand on that, if the key were to change it would mean old blob URLs in that environment would no longer be accessible, which would be quite weird, especially since blob URLs also serialize some origins into their identifier. And also, it seems that if two browsing context groups needed to share a blob they could/would share the object instead of the URL.
That doesn't seem that different from today? Blob objects can be shared across origins, while blob URLs can only be resolved by same origin originators. As such there are already plenty of cases where sharing a blob URL doesn't work but sharing a blob, and having the receiver create a blob URL from it does work.
It seems that blob objects could always be widely shared and that does not change. They essentially have no scope. Blob URLs had a scope that was undefined to some extent (see #135). This proposes to scope blob URLs more clearly, to the agent cluster they are created in as well as any new top-level browsing contexts (which we'd ideally force noopener on).
I don't understand why we would do this instead of just making blob URLs only loadable by contexts with the same StorageKey. It would seem better to lean on the partitioning we are pursuing in other APIs instead of introducing a new kind of isolation.
Apart from the issues discussed above that would not work well for top-level navigations to partitioned blob: URLs.
What are the issues above? I looked at the links but it was not obvious to me. Dynamic keying? Not all browsers are proposing to do that.
And I don't see why its problematic for top-level navigations. Can you explain that? If we have a StorageKey for the blob we can propagate that to the context. Just like how we are going to have partitioned service workers if they are registered with a partitioned StorageKey.
But even if we wanted to prevent blob URLs from partitioned StorageKeys from being navigated to, I don't see why we need to block a context with the same StorageKey as the blob from loading it as a subresource.
An upside of limiting Blob URL's to agent clusters is that it limits the potential for browser compat issues related to races for resolving Blob URLs against the Blob URLs being revoked. Right now resolve a Blob URL references the Blob URL Store like it's something that's synchronously accessible across all agent clusters. (I believe this leads to the situation described in #157 where Chrome has to use sync IPC when creating Blobs.)
That could alternately be addressed by specifying Blob resolution and Blob URL Store manipulations in a more multi-process-aware way. The previously referenced #157 would likely entail this because of the integration with storage.
(kind of aside, but Chrome doesn't actually need to use sync IPCs when creating Blobs anymore, at least not for any web-exposed API. We still do because some internal and chrome extension usage of blobs might otherwise have race conditions).
Blob URL creation however does indeed need sync IPCs in particular to solve situations like: 1) agent1 registers a blob URL; 2) agent1 postMessages said URL to some other agent2; 3) agent2 tries to resolve the blob URL. With chrome's IPC there is no guarantee that the registration in step 1 arrives in the browser process before the attempt to resolve from step 3 arrives. As you say, if all blob URL registrations were scoped to the agent cluster they are created in this would no longer be an issue, and we could possibly eliminate these as sync IPCs.
So with my implementer hat on I think scoping by agent cluster makes a lot of sense. I don't have a good idea how web compatible that would be, but it shouldn't be too hard to collect metrics for that.
With my spec editor hat on, I'm not sure what makes more sense; scoping by storage key seems like it would solve all the same issues, while probably being more web compatible. On the other hand it does feel a bit weird to me to use storage key for this as blob URLs don't really seem like anything storage related to me (but then we're also using storage key for things like broadcast channel, so that isn't much of an argument). Also I'd say that anything that drives down usage of blob URLs might be a good thing, so being as restrictive as we can while not breaking too much does seem attractive. Overall I don't feel particularly strongly either way.
It sounds like Firefox has shipped partitioning blob URL fetches by top-level site [1] and frame origin, and WebKit has shipped partitioning blob URL fetches by top-level origin [2] and frame origin. Also, Safari enforces noopener when blob URLs are window.opened and the blob URL origin is cross-origin from the opening page's top-level origin.
Chrome is investigating partitioning blob URL fetches by storage key (top-level site, frame origin, ancestor-chain-bit) and enforcing noopener on window.opened blob URLs when the opening page's top-level site is cross-site to the blob URL site.
From a spec perspective, would Firefox and Safari be supportive of updating the Blob URL spec to partition blob URL fetches by storage key and enforce noopener on window.opened blob URLs that are at least cross-site?
WebKit is investigating moving toward partitioning by a site-based storage key (either double-keying or triple-keying, TBD), but we can't commit to either scheme at this time. However, we are interested in defining a standard so we can avoid interop (and compat) issues.
Firefox has introduced an ancestor bit to the partition key implementation, and I believe it applies to Blob URL partitioning as well. Enforcing noopener on window.opened blob URLs when the opening page's top-level site is cross-site to the blob URL site sounds like a good idea, but we haven't implemented this behavior.
We are interested in aligning behavior across browser engines to avoid compatibility issues. So, defining a standard for Blob URL partitioning is probably the right approach.
Regarding enforcing noopener on cross-top-level-site Blob URLs, while reading the spec I learned that there are more cases than just window.open where window.opener can be set in the new window, specifically clicks on 'a' elements, clicks on 'area' elements, or form submissions where target="_blank" rel="opener" is used by those elements. We should enforce noopener in these cases as well, and IIUC WebKit/WebKit#7549 already made changes to handle this in WebKit. We'll work on adding WPTs for those additional cases and will capture this broader change in our subsequent spec PR as well unless anyone has any objections.
Activity
mkruisselbrink commentedon May 21, 2020
Limiting it like that doesn't seem too crazy to me, although I'm not entirely sure I understand the attack/threat model that defends against.
A blob URL can only be resolved when the page that created it is still alive, and when the page trying to fetch it is same origin with the original page. If that is the case, you might as well just BroadcastChannel to talk to the original page, rather than jumping through hoops with blob URLs?
Of course if storage partitioning blocks BroadcastChannel because of different top-level URLs things would be different, but in that case wouldn't it make more sense to partition blob URLs the same way as other communication mechanisms, rather than having them be partitioned even more?
mkruisselbrink commentedon May 21, 2020
Having said all that, for MediaSource blob URLs chrome already limits them to their agent cluster. And scoping all blob URLs to their agent cluster certainly would make the implementation a whole lot simpler (well, the top-level navigation case would still be tricky). So as an implementer agent cluster seems reasonable, as a spec editor I question if that is the right scoping level.
annevk commentedon May 22, 2020
The keying for storage seems like it will end up being dynamic (i.e., storage access). I think if we can avoid things being dynamically keyed that's preferable.
To expand on that, if the key were to change it would mean old blob URLs in that environment would no longer be accessible, which would be quite weird, especially since blob URLs also serialize some origins into their identifier. And also, it seems that if two browsing context groups needed to share a blob they could/would share the object instead of the URL.
smaug---- commentedon Aug 13, 2020
It would be a bit odd inconsistency if sharing objects worked, but sharing blob URLs didn't.
mkruisselbrink commentedon Aug 13, 2020
That doesn't seem that different from today? Blob objects can be shared across origins, while blob URLs can only be resolved by same origin originators. As such there are already plenty of cases where sharing a blob URL doesn't work but sharing a blob, and having the receiver create a blob URL from it does work.
smaug---- commentedon Aug 13, 2020
That is somewhat different inconsistency tough, since it is about cross-origin.
annevk commentedon Aug 14, 2020
It seems that blob objects could always be widely shared and that does not change. They essentially have no scope. Blob URLs had a scope that was undefined to some extent (see #135). This proposes to scope blob URLs more clearly, to the agent cluster they are created in as well as any new top-level browsing contexts (which we'd ideally force noopener on).
wanderview commentedon Jun 25, 2021
I don't understand why we would do this instead of just making blob URLs only loadable by contexts with the same StorageKey. It would seem better to lean on the partitioning we are pursuing in other APIs instead of introducing a new kind of isolation.
annevk commentedon Jun 25, 2021
Apart from the issues discussed above that would not work well for top-level navigations to partitioned
blob:URLs.wanderview commentedon Jun 25, 2021
What are the issues above? I looked at the links but it was not obvious to me. Dynamic keying? Not all browsers are proposing to do that.
And I don't see why its problematic for top-level navigations. Can you explain that? If we have a StorageKey for the blob we can propagate that to the context. Just like how we are going to have partitioned service workers if they are registered with a partitioned StorageKey.
But even if we wanted to prevent blob URLs from partitioned StorageKeys from being navigated to, I don't see why we need to block a context with the same StorageKey as the blob from loading it as a subresource.
asutherland commentedon Jun 25, 2021
An upside of limiting Blob URL's to agent clusters is that it limits the potential for browser compat issues related to races for resolving Blob URLs against the Blob URLs being revoked. Right now resolve a Blob URL references the Blob URL Store like it's something that's synchronously accessible across all agent clusters. (I believe this leads to the situation described in #157 where Chrome has to use sync IPC when creating Blobs.)
That could alternately be addressed by specifying Blob resolution and Blob URL Store manipulations in a more multi-process-aware way. The previously referenced #157 would likely entail this because of the integration with storage.
mkruisselbrink commentedon Jun 29, 2021
(kind of aside, but Chrome doesn't actually need to use sync IPCs when creating Blobs anymore, at least not for any web-exposed API. We still do because some internal and chrome extension usage of blobs might otherwise have race conditions).
Blob URL creation however does indeed need sync IPCs in particular to solve situations like: 1) agent1 registers a blob URL; 2) agent1 postMessages said URL to some other agent2; 3) agent2 tries to resolve the blob URL. With chrome's IPC there is no guarantee that the registration in step 1 arrives in the browser process before the attempt to resolve from step 3 arrives. As you say, if all blob URL registrations were scoped to the agent cluster they are created in this would no longer be an issue, and we could possibly eliminate these as sync IPCs.
So with my implementer hat on I think scoping by agent cluster makes a lot of sense. I don't have a good idea how web compatible that would be, but it shouldn't be too hard to collect metrics for that.
With my spec editor hat on, I'm not sure what makes more sense; scoping by storage key seems like it would solve all the same issues, while probably being more web compatible. On the other hand it does feel a bit weird to me to use storage key for this as blob URLs don't really seem like anything storage related to me (but then we're also using storage key for things like broadcast channel, so that isn't much of an argument). Also I'd say that anything that drives down usage of blob URLs might be a good thing, so being as restrictive as we can while not breaking too much does seem attractive. Overall I don't feel particularly strongly either way.
18 remaining items
recvfrom commentedon Sep 4, 2024
It sounds like Firefox has shipped partitioning blob URL fetches by top-level site [1] and frame origin, and WebKit has shipped partitioning blob URL fetches by top-level origin [2] and frame origin. Also, Safari enforces noopener when blob URLs are window.opened and the blob URL origin is cross-origin from the opening page's top-level origin.
Chrome is investigating partitioning blob URL fetches by storage key (top-level site, frame origin, ancestor-chain-bit) and enforcing noopener on window.opened blob URLs when the opening page's top-level site is cross-site to the blob URL site.
From a spec perspective, would Firefox and Safari be supportive of updating the Blob URL spec to partition blob URL fetches by storage key and enforce noopener on window.opened blob URLs that are at least cross-site?
CC @miketaylr
[1] https://groups.google.com/a/mozilla.org/g/dev-platform/c/1gt1CVIoffc/m/cFloZuPPAAAJ
[2] sysrqb/webkit@7f2ea8f
annevk commentedon Sep 5, 2024
cc @sysrqb
sysrqb commentedon Sep 5, 2024
WebKit is investigating moving toward partitioning by a site-based storage key (either double-keying or triple-keying, TBD), but we can't commit to either scheme at this time. However, we are interested in defining a standard so we can avoid interop (and compat) issues.
recvfrom commentedon Sep 5, 2024
CC @artines1 for a Firefox perspective
artines1 commentedon Sep 5, 2024
Firefox has introduced an ancestor bit to the partition key implementation, and I believe it applies to Blob URL partitioning as well. Enforcing
noopeneron window.opened blob URLs when the opening page's top-level site is cross-site to the blob URL site sounds like a good idea, but we haven't implemented this behavior.We are interested in aligning behavior across browser engines to avoid compatibility issues. So, defining a standard for Blob URL partitioning is probably the right approach.
CC @bvandersloot-mozilla
recvfrom commentedon Oct 28, 2024
Thanks for the feedback everyone! I have PRs up to partition Blob URL fetches and revocation by Storage Key:
Regarding enforcing noopener on cross-top-level-site Blob URLs, while reading the spec I learned that there are more cases than just window.open where window.opener can be set in the new window, specifically clicks on 'a' elements, clicks on 'area' elements, or form submissions where
target="_blank" rel="opener"is used by those elements. We should enforce noopener in these cases as well, and IIUC WebKit/WebKit#7549 already made changes to handle this in WebKit. We'll work on adding WPTs for those additional cases and will capture this broader change in our subsequent spec PR as well unless anyone has any objections.recvfrom commentedon Oct 31, 2024
I have a PR up for the noopener changes as well:
Also, on the Chrome side we recently sent out an Intent to Prototype and Ship for these changes: https://groups.google.com/a/chromium.org/g/blink-dev/c/erVBugcYwRc
Enforce noopener on cross-top-level-site blob URLs
Partition blob: URL fetches by storage key
recvfrom commentedon Jan 9, 2025
The spec changes from my last two comments have now landed. Shall we close this issue, or is there more work that we should do on this?
mkruisselbrink commentedon Jan 9, 2025
Yeah, I think we can close this.
Enforce noopener on cross-top-level-site blob URLs
Partition blob: URL fetches by storage key