w3c / webauthn

Web Authentication: An API for accessing Public Key Credentials
https://w3c.github.io/webauthn/
Other
1.16k stars 166 forks source link

Add a way to use webauthn without Javascript #1255

Open ignaloidas opened 5 years ago

ignaloidas commented 5 years ago

Adding a way to use webauthn without Javascript should be considered. For example most Tor users have Javascript always disabled, and having a way to use webauthn without JS would allow use of 2FA in Tor. Also, some projects want to be fully usable without the use of JS, and having a way to use 2FA would open the way for those projects too. I'm not too sure how it should be implemented though. Maybe <input type="webauthn">?

pabs3 commented 9 months ago

@rlin1 got a link to the FIDO in TLS initiative?

-- bye, pabs

https://bonedaddy.net/pabs3/

rlin1 commented 9 months ago

@rlin1 got a link to the FIDO in TLS initiative? -- bye, pabs https://bonedaddy.net/pabs3/

https://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2020-04 https://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2021-02 https://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2023-01

MasterKale commented 8 months ago

Moving this to "Futures" as potential work for L4.

arianvp commented 8 months ago

I've started experimenting with a Form-Associated Custom Element (FACE) that allows you to use Webauthn with "just" HTML.

FACE is cool as you can define how the element contributes to form submission. This makes the element I define function very similar to the old <keygen>. It just send the clientDataJSON and signature as a multipart file.

Of course you need the javascript to define the element. But can serve as a playground to find the right html interface

Example of conditional UI

<script type="module" src="./index.js"></script>

<!-- this form either redirects to  login.html?username=blah to  do a modal flow -->
<!-- Or it triggers the webauthn autocomplete and triggers the form below -->
<form method="get" action="login.html">
    <label for="username">User name</label>
    <input type="text" name="username" id="username" autocomplete="username webauthn">
    <input type="submit" value="Log in">
</form>
<!-- this form gets triggered by the `input` element marked `webauthn` -->
<!-- encodes the signature and clientDataJSON as  multipart/form-data -->
<form method="post" action="login.html" enctype="multipart/form-data">
    <public-key-credential challenge="AAAA" name="credential" conditional />
</form>

Example of modal UI:

<script type="module" src="./index.js"></script>
<form method="post" enctype="multipart/form-data">
    <public-key-credential 
        name="credential" 
        allow-credentials="h1OZg6bnPuktiGIlE39YwY9VRTw" 
        challenge="AAAA" />
    <input type="submit" value="Login with Passkey">
</form>

https://github.com/arianvp/public-key-credential-element/blob/main/index.ts

NOTE: There seems to be some bugginess in Safari where the <public-key-credential conditional> element can not be in the same parent form as the <input type=text autocomplete=webauthn> input or the autocomplete UI will not trigger and the conditional promise never resolves. Feel this is some kind of weird bug

dwaite commented 8 months ago

Since WebAuthn L3 defines a JSON form for the request and response messages, I would be motivated to use this rather than defining a new decomposition of WebAuthn API messages.

I could readily imagine this as JSON encoded in an attribute on an object or new tag, or as a reference to a , although the second may have CSP ramifications I'm not familiar with.

arianvp commented 8 months ago

I don't really see the benefit of that. On the other side as RP you're gonna have to change that base64 string to a binary again anyway. Why not cut the middleman and send the binary signature as a binary directly?

Using form elements for sending data seems to be the most natural way to express these things in my opinion. All the infrastructure for it is already there. Lets not reinvent the wheel.

ryanhiebert commented 8 months ago

@arianvp I'm still a fairly naive bystander, but what you're proposing looks really good to me, and very much along the lines of what I was hoping for. That (IIUC) the custom element you've defined would be an empty unknown element if JS isn't working or the script is missing is excellent for progressive enhancement. This, or something close to it, it the kind of API I'd like to see, from my current understanding of the problem space.