MasterKale / SimpleWebAuthn

WebAuthn, Simplified. A collection of TypeScript-first libraries for simpler WebAuthn integration. Supports modern browsers, Node, Deno, and more.
https://simplewebauthn.dev
MIT License
1.62k stars 137 forks source link

`AbortError` when calling `startRegistration` on MacOS Safari #385

Closed hwhmeikle closed 1 year ago

hwhmeikle commented 1 year ago

Describe the issue

When calling startRegistration in MacOS Safari an AbortError: Authentication ceremony was sent an abort signal error occurs. Strangely, If called again it successfully starts the registration process.

Reproduction Steps

  1. Open up Safari on MacOS
  2. Run the example app
  3. Click 'Register'
  4. See error
  5. Click 'Register' again
  6. Observe that it works

Expected behavior

I would expect that it does not error the first time clicking 'Register'

Code Samples + WebAuthn Options and Responses

Can be replicated by running the example app locally.

Dependencies

SimpleWebAuthn Libraries

$ npm list --depth=0 | grep @simplewebauthn
├── @simplewebauthn/browser@7.2.0
├── @simplewebauthn/server@7.2.0
# ...

Additional context

Looks like it could be related to this issue maybe: https://github.com/MasterKale/SimpleWebAuthn/discussions/351

hwhmeikle commented 1 year ago

In hindsight this might be the same as: https://github.com/MasterKale/SimpleWebAuthn/discussions/351

MasterKale commented 1 year ago

Please fill out ALL of the issue template. "N/A" for sections not immediately relevant is fine, but omitting whole sections is no bueno. I created the template because it includes all of the common questions I have for people who drop an issue here, questions like "which browser and its version" and "which OS and version." Once that info is in there we can continue.

hwhmeikle commented 1 year ago

My apologies - I've filled out the additional sections.

MasterKale commented 1 year ago

Hmm, so while playing around with this I realized it's probably a bug with Safari, not with the example project.

I recreated the issue in vanilla HTML + JS, the AbortError is expected but there's a NotAllowedError: Operation Failed error being thrown when you try to call .create() with conditional UI (i.e. .get()) running that I think is a bug in Safari:

Screenshot 2023-05-22 at 5 15 08 PM

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="startReg">Start modal registration</button>
    <button id="startAuth">Start modal authentication</button>
    <form action="">
      <input
        type="email"
        name="email"
        id="email"
        autocomplete="webauthn username"
      />
    </form>
    <script>
      const abortController = new AbortController();

      // Start conditional UI
      navigator.credentials
        .get({
          publicKey: {
            challenge: new Uint8Array(16).fill(0),
            allowCredentials: [],
          },
          mediation: "conditional",
          signal: abortController.signal,
        })
        .then(console.log)
        .catch(console.error);

      // Start modal registration
      document.getElementById("startReg").addEventListener("click", () => {
        abortController.abort();
        navigator.credentials.create({
          publicKey: {
            challenge: new Uint8Array(16).fill(0),
            rp: { id: "localhost", name: "localhost" },
            user: {
              id: new Uint8Array(16).fill(0),
              name: "Username",
              displayName: "Username",
            },
            pubKeyCredParams: [{ alg: -7, type: "public-key" }],
          },
        });
      });

      // Start modal auth
      document.getElementById("startAuth").addEventListener("click", () => {
        navigator.credentials.get({
          publicKey: {
            challenge: new Uint8Array(16).fill(0),
          },
        });
      });
    </script>
  </body>
</html>

I'm going to log this as a bug with WebKit since Chrome handles this scenario as I'd expect. It might be the oddity of trying to call .create() when you're on a page dedicated for auth, but I still think it's a bug. I'll keep this issue updated as things develop.

MasterKale commented 1 year ago

I logged this as a bug here:

https://bugs.webkit.org/show_bug.cgi?id=257176

Let's see what Apple says.

hwhmeikle commented 1 year ago

yeah definitely seems like Safari weirdness - observed it my own project initially. Thanks for logging that bug.

MasterKale commented 1 year ago

I'm going to convert this to a Discussion for now since it doesn't appear to be a library issue.