Re: [webauthn] Provide request deserialization, response serialization (#1683)

> > As I'm reading this, you are expressing an opinion that WASM is a "demo" or a "toy" language, and not something you need to seriously consider in the surface area of webauthn and how it interacts with a browser.
> I'm sorry if my message was interpreted that way. I'm trying to verify any requirements you may have.
> If it helps, WASM instructions _or_ Javascript code consuming authentication assertions within the browser has limited utility. You are making an authentication assertion into a locally held and easily user introspectable box. Whether you are protecting e.g. an IndexedDB database by a locally prompted password or WebAuthn, the data is still a local database, exposed one pane over via developer tools.
> Remote infrastructure, whether running on top of WASM or a virtual or native machine architecture would be normally where you would produce challenges and verify the assertion. The choice of execution architecture here should not have an impact over say, the choice of programming language.
> There have been proposals to add e.g. a way to unlock a symmetric key with WebAuthn, which changes this equation significantly - but I'd argue serializing this symmetric key (or making it exportable in general) is probably a bad idea.

I think you are over thinking this. Just imagine that instead of JS, replace it with WASM. The architecture is still:

Server -- http --> browser -> JS/WASM -> navigator.credentials

Just replace the dynamic JS parts with WASM, and you get what what I'm asking.

> > I am extremely confused by what you are asking here, because I think you are confused about what I'm requesting.
> To ask tersely - you asked for considerations. I asked for what those considerations would be.

Okay, to be explicit.

Today, when you perform a browser fetch request to a webauthn endpoint of a server, you receive a JSON response. Deserialising that JSON into the WASM or JS context, it is *not possible* to create a Uint8Array. As a result, the structure has an array of bytes, but in a different format.

This means that any RP today MUST create dynamic components that MUST execute in the browser, that MUST alter the content of any structure which is intended to be passed into navigator.credentials apis. This is commonly achieved by base64url encoding and decoding the fields. 

So there a number of potential ways to tackle this:

1. Provide a "common" javascript blob/file that can be consumed that does the base64 decode/encode as required.
2. Convince browsers to implement a platform api which allows a JS/WASM object that does the decode/encode as required.
3. Alter the webauthn specification such that the navigator.credentials apis accept either base64 OR uint8array versions of the fields (per )

So let's consider this from the JS/WASM context.

1. Linking and binding to an external piece of javascript, which likely exists in the npm ecosystem may not be easy. In fact, just providing this common js blob does not even need the webauthn group involved, you could setup a project on github today to do this.
2. and 3. both require webauthn to step in and convince browsers to extend their navigator.credentials apis, and these apis can already be consumed from JS and WASM equally through platform bindings. 

> > Both of which would be "breaking" changes to what a browser provides, and are desperately needed both so that RP's no longer need JS/WASM to mangle incoming requests so that nav.cred can understand it, but also because a large number of parameters in Webauthn an unsigned which opens the door to a number of potential security issues which extensions poorly defend from.
> There are five buckets of information, somewhat blended together
> 1. The unprotected request from the relying party
> 2. Client collected data, such as the origin requesting WebAuthn, and client-specified authenticator extensions like CredProtect
> 3. The response to the unprotected request by the authenticator, signed by the previously negotiated public credential (on get) or potentially signed by attestation (on create), containing some of the information from 1 & 2.
> 4. Non-integrity-protected client information on the response. This includes getTransport() and getClientExtensionResults()
> 5. Helper information and Helper API for extracting some information returned from 3 in a non-integrity-protected manner. This includes the credential [[identifier]], getAttestationObject(), and getPublicKey().
> These pieces represent multiple actors and multiple sets of security considerations/attacker models. That is why I hope the helper information (like getPublicKey and getAuthenticatorData) are not serialized as part of responses, as correct validation becomes that much harder if someone does part of their processing on e.g. the non-integrity-verified copy authenticator data. I'd much rather tooling like Webauthn-RS generate their own Helper API as appropriate from the serialized responses.

I think this section of the comment doesn't apply to the JS/WASM discussion, but I have discussed before about this issue within this group as this has led to CVE's in the past. If this change was to be accepted, then it would be viable to actually potentially correct this long standing defect in the webauthn specification such that the entire chain of communication is verified rather than small elements. 

GitHub Notification of comment by Firstyear
Please view or discuss this issue at using your GitHub account

Sent via github-notify-ml as configured in

Received on Friday, 21 January 2022 02:05:30 UTC