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.63k stars 137 forks source link

add `127.0.0.1` as a valid domain #615

Closed sacrosanctic closed 1 month ago

sacrosanctic commented 1 month ago

Describe the issue

Currently, i get this error

Uncaught (in promise) SecurityError: 127.0.0.1 is an invalid domain
    at identifyAuthenticationError (@simplewebauthn_browser.js?v=b0e333ee:275:14)
    at startAuthentication (@simplewebauthn_browser.js?v=b0e333ee:328:11)Caused by: SecurityError: This is an invalid domain.

127.0.0.1 is considered a secure context (ref). Please consider adding it.

SimpleWebAuthn Libraries

$ pnpm list --depth=0 | grep @simplewebauthn
@simplewebauthn/browser 9.0.1
@simplewebauthn/server 9.0.3
@simplewebauthn/types 9.0.1

Additional context

the file in question https://github.com/MasterKale/SimpleWebAuthn/blob/b1ddca7aa1515ce8ca045aaf31642e29d56a2500/packages/browser/src/helpers/isValidDomain.ts#L9-L15

MasterKale commented 1 month ago

Hello @sacrosanctic, unfortunately adding this won't do anything about the fact that neither Chrome, Firefox, nor Safari recognize 127.0.0.1 as a valid domain for invoking WebAuthn. Here's what happens when a page served at http://127.0.0.1:8000 tries to call navigator.credentials.get() via startAuthentication():

startAuthentication(options, true)
  .then(...)
  .catch(err => {
    console.error('(Autofill)', err, err.cause);
  });

Chrome:

chrome Chrome raises SecurityError: This is an invalid domain.

Firefox:

firefox Firefox raises DOMException: The operation is insecure.

Safari:

safari Safari raises SecurityError: The effective domain of the document is not a valid domain.

MasterKale commented 1 month ago

While technically 127.0.0.1 is considered just as valid as localhost for establishing a Secure Context...

https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy

  1. If origin’s host matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy".
  2. If the user agent conforms to the name resolution rules in [let-localhost-be-localhost] and one of the following is true:
    • origin’s host is "localhost" or "localhost."
    • origin’s host ends with ".localhost" or ".localhost."

then return "Potentially Trustworthy".

All of the main browser vendors have implemented internal checks such that localhost is only really valid when calling WebAuthn. There's nothing I can do about this at the library level, so I'm going to close this out for now. I'm happy to update isValidDomain() in the future to say 127.0.0.1 is valid if this browser-level behavior changes.

MasterKale commented 1 month ago

Oh actually the real reason 127.0.0.1 won't ever be a valid domain in the context of WebAuthn is because WebAuthn's origin binding requires a domain name to help determine what RP ID to scope a credential to. And there are too many footguns with IP addresses and public key cryptography as well that prevent IP addresses from being considered for RP IDs.