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

Allow using Crypto.getRandomValues() in Shadow Realms #361

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Ms2ger
Copy link

@Ms2ger Ms2ger commented Jan 23, 2024

Note that this depends on the introduction of UniversalGlobalScope in whatwg/html#9893.

Closes #338

The following implementers have shown interest:

The following tasks have been completed:

Implementation issues:


Preview | Diff

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

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

This exposes much more in Shadow Realms, no?

@Ms2ger
Copy link
Author

Ms2ger commented Jan 23, 2024

My understanding at this point is that we will not expose anything behind [SecureContext] in ShadowRealms. I don't think that's entirely clear from the prose in IDL yet; I'm looking into clarifying that at the moment.

@annevk
Copy link
Member

annevk commented Jan 23, 2024

I think it's worth adding explicit [Exposed=Window,Worker] to the [SecureContext] members and maybe even asserting that needs to be present for [SecureContext] members when their corresponding class has [Exposed=*]. Seems a tad too magical otherwise.

But maybe we should also take a step back and have a discussion on that as it's not clear to me what principles are behind it. At least to me it seems somewhat reasonable to offer UUIDs. But perhaps we don't want the additional [SecureContext] bookkeeping? I can understand that, especially for a v1.

@twiss
Copy link
Member

twiss commented Jan 23, 2024

My understanding at this point is that we will not expose anything behind [SecureContext] in ShadowRealms. I don't think that's entirely clear from the prose in IDL yet; I'm looking into clarifying that at the moment.

I don't know that much about ShadowRealms, but I would intuitively expect [SecureContext] to expose things if the ShadowRealm was created in a secure context. If that's not the intention I personally agree with Anne that it might make sense to make that explicit using [Exposed].


A more general comment: this PR only talks about Shadow Realms but the diff makes the Crypto interface [Exposed=*], which also exposes it (including SubtleCrypto and randomUUID) for Worklets (as discussed in #338), right? That might not be an issue, but if you want to expose it for Shadow Realms only, you might want a more specific [Exposed] attribute. Alternatively, if you want to expose it everywhere, I think it'd be good to make that clear in the PR description etc.

Also, the WebIDL spec says:

[Exposed=*] is to be used with care. It is only appropriate when an API does not expose significant new capabilities. If the API might be restricted or disabled in some environments, it is preferred to list the globals explicitly.

That being said, I'm not sure if there's any significant concern about exposing crypto.getRandomValues everywhere, and the other members are gated behind [SecureContext], so perhaps that already sufficiently addresses the concern. But, it might still seem safer to explicitly list the places where it should be exposed?

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

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

This looks correct, but you should make it clear in OP what other PR this depends on and that this cannot merge before that as UniversalGlobalScope is not a thing as far as I know.

ArrayBufferView getRandomValues(ArrayBufferView array);
[SecureContext] DOMString randomUUID();
[Exposed=*, SecureContext] DOMString randomUUID();
Copy link
Member

@lukewarlow lukewarlow Nov 26, 2024

Choose a reason for hiding this comment

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

Isn't this Exposed=* superfluous because the whole interface is exposed *?

Copy link

Choose a reason for hiding this comment

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

I think you're right. Fixed.

@ptomato ptomato force-pushed the expose-getRandomValues branch from 89b3cc1 to 60d2b38 Compare January 16, 2025 20:35
@ptomato
Copy link

ptomato commented Jan 16, 2025

We now believe SubtleCrypto meets the requirements for Exposed=* as in https://www.w3.org/TR/design-principles/#expose-everywhere, so updated this PR to reflect that.

@twiss
Copy link
Member

twiss commented Jan 17, 2025

Interesting, thanks for the reference.

I think you're right for getRandomValues and randomUUID (there's probably a pedantic argument about whether reading from /dev/urandom counts as I/O, but since it doesn't cause observable side effects I'd assume that's probably fine), but I'm not so sure about SubtleCrypto, because the linked text says:

anything relying on an event loop should not be exposed everywhere. Not all global scopes have an event loop.

And, as more properly spelled out since #386, SubtleCrypto does currently require an event loop (though, see also #389).

I'm not super sure what the practical implications of that are and which scopes don't have an event loop, but it does seem to imply to me that the scopes where SubtleCrypto is exposed should still be explicitly listed?

(As an aside, if we want a crypto API in the scopes without an event loop, we could reconsider making a synchronous version of SubtleCrypto, which doesn't need an event loop, but that would be a fairly large endeavor, of course.)

@ptomato
Copy link

ptomato commented Jan 17, 2025

Ah, thanks for the pointers. If I'm understanding the discussion there correctly, I'd say that it depends on whether the async operations are written as described in #389 (comment) or not. Anne mentioned there is an observable difference between queuing a task and queuing a microtask. Queuing a microtask doesn't require an event loop (after all, Promise.resolve().then(callback) queues a microtask and works just fine in scopes with no event loop.)

AudioWorklet is the main example of a scope that has no event loop. I'd say if the "queue a microtask with the remaining steps" approach is adopted, then it's OK to expose SubtleCrypto everywhere. If not, then we'd have to avoid exposing it in AudioWorklet and therefore also in ShadowRealm (because you can create a ShadowRealm in an AudioWorklet scope, which also won't have an event loop.)

So for the time being it seems best if I remove the changes to SubtleCrypto/CryptoKey from this PR.

The whole interface is Exposed=*, so this doesn't need to be annotated
separately.
@ptomato ptomato force-pushed the expose-getRandomValues branch from a657122 to 44d6531 Compare January 17, 2025 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can we expose Crypto/SubtleCrypto to all Worklet / all scopes?
5 participants