webauthn-open-source / fido2-lib

A node.js library for performing FIDO 2.0 / WebAuthn server functionality
https://webauthn.io
MIT License
389 stars 118 forks source link

fido2-lib with android and ios #149

Open Elolawyn opened 6 months ago

Elolawyn commented 6 months ago

Hi, I am executing a demo with fido2-lib on the backend with mocked data. The library I am using (react-native-passkey) on the device seems to be working because the passkey generation and usage system dialogs appears and the library is returning the following clientDataObj to be checked by fido2-lib:

On iOS, the PasskeyRegistrationResult the library is returning provided me the following clientDataObj:

{
  type: 'webauthn.create',
  challenge: 'challenge_properly_formed',
  origin: 'https://my-web.com'
}

However, on android, the library returns the following clientDataObj:

{
  type: 'webauthn.create',
  challenge: 'challenge_properly_formed',
  origin: 'android:apk-key-hash:HASH',
  androidPackageName: 'com.org.package'
}

On the server side, the following fido2-lib method is working on iOS:

const f2l = new Fido2Lib({
    timeout: 42,
    rpId: "my-web.com",
    rpName: "Web",
    challengeSize: 64,
    attestation: "direct",
    cryptoParams: [-7, -257],
    authenticatorAttachment: "platform",
    authenticatorRequireResidentKey: true,
    authenticatorUserVerification: "required"
});

const expectedAttestationResult: ExpectedAttestationResult = {
  challenge: 'challenge_properly_formed',
  origin: 'https://my-web.com',
  factor: 'first'
}

const attestationResult: Fido2AttestationResult = await f2l.attestationResult(
  clientAttestationResult, // Returned by react-native-passkey on the phone, provided to server end-point
  expectedAttestationResult
)

How should I configure origins for both apps?

In android's case, attestationResult returns Error: clientData origin did not match expected origin.

ranierimazili commented 6 months ago

Have you set the domain for Android as documented here: https://github.com/f-23/react-native-passkey?tab=readme-ov-file#android ? Maybe you have to setup the same domain for both platforms (iOS and Android) so both will use the same origin when creating the attestationResult.

Elolawyn commented 6 months ago

Yes, i properly configured the assetlinks.json file (or at least, i think i did).

I asked in the react-native-passkey repository and the result the library returns seems to be valid (clientDataObj). The issue: https://github.com/f-23/react-native-passkey/issues/26

I guess i need to setup something on the server side to decide the origin to use in ExpectedAttestationResult because that method only accepts one, right? And calculate the origin too, because i swear (but right now i can't confirm) the origin returned by the library was not the same as the one i put inside assetlinks.json.

davidthornton commented 5 months ago

Hi team, this appears to be related to the W3C late-stage change from strict text matching origins to "registrable subdomains"...

I believe it's a valid setup to have a relying party host a web page at:

www.example.com

But set its rpId to example.com which would mean that a browser sets the origin to:

https://www.example.com

And a native context would set it to:

https://example.com

Because, among other reasons, Apple and Google are still requiring or have only newly shifted to using a * wildcard in the app entitlements/allow lists for domain association/asst linking...

My question then becomes, can/should we move this concept of registrable subdomain into fido2-lib server side logic?

Just so we know it's standard security practice, rather than doing that in the calling code? Noting that I am committing this issue URL to main in a comment 😅

JamesCullum commented 5 months ago

Thanks for the good discussion - www.example.com is not the same as example.com, as www is just a valid subdomain that can contain everything.

Do the specs require https anywhere? We could try to add the protocol if unspecified, but I'm afraid it would lead to issues with other applications (eg apps).

kylebrowning commented 3 months ago

Well, I was have a very similar issue on the iOS side but I seemed to have resolved that.

Now Im getting id and credId were not the same and I can't seem to figure out where credId is coming from.

Any ideas?