diff options
Diffstat (limited to 'packages/server/src')
3 files changed, 57 insertions, 4 deletions
diff --git a/packages/server/src/authentication/verifyAuthenticationResponse.test.ts b/packages/server/src/authentication/verifyAuthenticationResponse.test.ts index 212de2c..b78a5c4 100644 --- a/packages/server/src/authentication/verifyAuthenticationResponse.test.ts +++ b/packages/server/src/authentication/verifyAuthenticationResponse.test.ts @@ -260,6 +260,54 @@ test('should throw an error if RP ID not in list of possible RP IDs', async () = }).toThrow(/unexpected rp id/i); }); +test('should pass verification if custom challenge verifier returns true', () => { + const verification = verifyAuthenticationResponse({ + credential: { + 'id': 'AaIBxnYfL2pDWJmIii6CYgHBruhVvFGHheWamphVioG_TnEXxKA9MW4FWnJh21zsbmRpRJso9i2JmAtWOtXfVd4oXTgYVusXwhWWsA', + 'rawId': 'AaIBxnYfL2pDWJmIii6CYgHBruhVvFGHheWamphVioG_TnEXxKA9MW4FWnJh21zsbmRpRJso9i2JmAtWOtXfVd4oXTgYVusXwhWWsA', + 'response': { + 'authenticatorData': 'SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFYftypQ', + 'clientDataJSON': 'eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZXlKaFkzUjFZV3hEYUdGc2JHVnVaMlVpT2lKTE0xRjRUMnB1VmtwTWFVZHNibFpGY0RWMllUVlJTbVZOVmxkT1psODNVRmxuZFhSbllrRjBRVlZCSWl3aVlYSmlhWFJ5WVhKNVJHRjBZU0k2SW5OcFoyNU5aVkJzWldGelpTSjkiLCJvcmlnaW4iOiJodHRwOi8vbG9jYWxob3N0OjgwMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9', + 'signature': 'MEUCIByFAVGfkoKPEzynp-37BX_HOXSaC6-58-ELjB7BG9opAiEAyD_1mN9YAPrphcwpzK3ym2Xx8EjAapgQ326mKgQ1pW0', + 'userHandle': 'internalUserId' + }, + 'type': 'public-key', + 'clientExtensionResults': {} + }, + expectedChallenge: (challenge: string) => { + const parsedChallenge: { actualChallenge: string; arbitraryData: string; } = JSON.parse( + base64url.decode(challenge), + ); + return parsedChallenge.actualChallenge === 'K3QxOjnVJLiGlnVEp5va5QJeMVWNf_7PYgutgbAtAUA'; + }, + expectedOrigin: 'http://localhost:8000', + expectedRPID: 'localhost', + authenticator: { + credentialID: base64url.toBuffer( + 'AaIBxnYfL2pDWJmIii6CYgHBruhVvFGHheWamphVioG_TnEXxKA9MW4FWnJh21zsbmRpRJso9i2JmAtWOtXfVd4oXTgYVusXwhWWsA' + ), + credentialPublicKey: base64url.toBuffer( + 'pQECAyYgASFYILTrxTUQv3X4DRM6L_pk65FSMebenhCx3RMsTKoBm-AxIlggEf3qk5552QLNSh1T1oQs7_2C2qysDwN4r4fCp52Hsqs' + ), + counter: 0, + }, + }); + + expect(verification.verified).toEqual(true); +}); + +test('should fail verification if custom challenge verifier returns false', () => { + expect(() => { + verifyAuthenticationResponse({ + credential: assertionResponse, + expectedChallenge: (challenge) => challenge === 'willNeverMatch', + expectedOrigin: assertionOrigin, + expectedRPID: 'dev.dontneeda.pw', + authenticator: authenticator, + }); + }).toThrow(/custom challenge verifier returned false/i); +}); + /** * Assertion examples below */ diff --git a/packages/server/src/authentication/verifyAuthenticationResponse.ts b/packages/server/src/authentication/verifyAuthenticationResponse.ts index cd83be3..c1ccc65 100644 --- a/packages/server/src/authentication/verifyAuthenticationResponse.ts +++ b/packages/server/src/authentication/verifyAuthenticationResponse.ts @@ -14,7 +14,7 @@ import isBase64URLString from '../helpers/isBase64URLString'; export type VerifyAuthenticationResponseOpts = { credential: AuthenticationCredentialJSON; - expectedChallenge: string; + expectedChallenge: string | ((challenge: string) => boolean); expectedOrigin: string | string[]; expectedRPID: string | string[]; authenticator: AuthenticatorDevice; @@ -82,7 +82,13 @@ export default function verifyAuthenticationResponse( } // Ensure the device provided the challenge we gave it - if (challenge !== expectedChallenge) { + if (typeof expectedChallenge === 'function') { + if (!expectedChallenge(challenge)) { + throw new Error( + `Custom challenge verifier returned false for registration response challenge "${challenge}"`, + ); + } + } else if (challenge !== expectedChallenge) { throw new Error( `Unexpected authentication response challenge "${challenge}", expected "${expectedChallenge}"`, ); diff --git a/packages/server/src/registration/verifyRegistrationResponse.ts b/packages/server/src/registration/verifyRegistrationResponse.ts index a2a4cf6..f9c111d 100644 --- a/packages/server/src/registration/verifyRegistrationResponse.ts +++ b/packages/server/src/registration/verifyRegistrationResponse.ts @@ -26,13 +26,12 @@ import verifyApple from './verifications/verifyApple'; export type VerifyRegistrationResponseOpts = { credential: RegistrationCredentialJSON; - expectedChallenge: string | ChallengeVerifier; + expectedChallenge: string | ((challenge: string) => boolean); expectedOrigin: string | string[]; expectedRPID?: string | string[]; requireUserVerification?: boolean; supportedAlgorithmIDs?: COSEAlgorithmIdentifier[]; }; -export type ChallengeVerifier = (challenge: string) => boolean; /** * Verify that the user has legitimately completed the registration process |