Bug 262775 - opening popup from Web Crypto API promise in click handler should be considered user-initiated
Summary: opening popup from Web Crypto API promise in click handler should be consider...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: UI Events (show other bugs)
Version: Safari 17
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2023-10-06 03:48 PDT by tyr.asd
Modified: 2023-11-10 04:35 PST (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description tyr.asd 2023-10-06 03:48:23 PDT
For example, when implementing the PKCE protocol for OAuth2, one wants to use the Web Crypto API to generate the hash for the code challenge (https://datatracker.ietf.org/doc/html/rfc7636#section-4.2). However, Safari does prevent to open a popup window using the generated SHA-256 hash from within the promise returned by the Web Crypto API.

Other browsers (e.g. Chrome, Firefox) do allow opening a popup from within the Web Crypto API promise as long as the initial click is user initiated.


Example to reproduce:

```
button.onclick = function() {
    const dummy_verifier = Uint8Array.of(1,2,3);
    window.crypto.subtle.digest('SHA-256', dummy_verifier).then(hash => {
        const dummy_challenge = btoa(hash);
        window.open(`https://example.com?challenge=${dummy_challenge}`);
    });
}
```
Comment 1 Radar WebKit Bug Importer 2023-10-13 03:49:13 PDT
<rdar://problem/116913024>
Comment 2 sideshowbarker 2023-11-09 22:15:41 PST
Can you please explain what exactly expected behavior is?

Or better yet, can you please post a minimal reproducible example?

See https://stackoverflow.com/help/minimal-reproducible-example for some guidance on what needs to be included in a minimal reproducible example (that’s mostly general guidance, not specific to Stack Overflow questions, but applicable to any situation — for example, in an issue like this one — where you want others to try to reproduce some behavior you’ve observed.

When I try with the following document:

<!doctype html>
<button>Press this</button>
<script>
document.querySelector("button").onclick = function() {
    const dummy_verifier = Uint8Array.of(1,2,3);
    window.crypto.subtle.digest('SHA-256', dummy_verifier).then(hash => {
        const dummy_challenge = btoa(hash);
        window.open(`https://example.com?challenge=${dummy_challenge}`);
    });
}
</script>

…and I serve that document from a local HTTP server — for example, at http://localhost:8000/index.html — and I press the “Press this” button, what I observe in all browsers, including Safari 17.2, is that the browser opens a new window to, e.g., https://example.com/?challenge=W29iamVjdCBBcnJheUJ1ZmZlcl0=

That is, the behavior I observe in Safari 17.2 is no different than the behavior I observe in Firefox or Chrome.

So is there some other additional behavior that I should be looking for? I mean, is there any behavior other than the new window after I click the button?
Comment 3 tyr.asd 2023-11-10 02:58:49 PST
Yes, the document you posted is exactly the minimal reproducible example I had in mind. Sorry for omitting the HTML boilerplate in my original post. And yes, the expected behavior is that the popup simply opens without being blocked. There's no additional behavior to look out for.

I tested this now again with the latest publicly available versions of Safari (17.0 on Mac, as well as 17.1 on iPhone 15), which both have the issue that the popup is blocked.

It would be great if this was already fixed between versions 17.0/1 and 17.2. But just to double-check: Was your test on a fresh install with default settings? Did you perhaps had your settings changed at some point to allow popups on the localhost domain, or something like that?
Comment 4 sideshowbarker 2023-11-10 04:08:41 PST
I don’t know what relevant settings I may have that are non-default, but to be clear: Does the popup blocking you’re describing only happen when you try to use window.open with a hash from window.crypto.subtle.digest, or does it also happen in other cases where you try window.open?

For example, does the popup blocking in Safari also happen if you try this:

<!doctype html>
<button>Press this</button>
<script>
document.querySelector("button").onclick = function() {
        window.open("https://example.com");
}
</script>
Comment 5 tyr.asd 2023-11-10 04:35:28 PST
the blocking does not happen in the simple case where `window.open` is called outside of the promise `.then` method.

I have compiled a list of different cases:
https://jsfiddle.net/tyrasd/jv12wz93/18/

On Firefox or Chrome, all cases work fine. On Safari, only the first ("direct") case works, while all other cases are blocked.