Improve WebAuthn error detection for invalid data (#946)

This commit is contained in:
Oscar Hinton 2021-04-23 21:07:15 +02:00 committed by GitHub
parent 2392d34ed8
commit d71d0d9af6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 22 deletions

View File

@ -27,6 +27,20 @@ export function b64Decode(str: string) {
}).join(''));
}
export function parseWebauthnJson(jsonString: string) {
const json = JSON.parse(jsonString);
const challenge = json.challenge.replace(/-/g, '+').replace(/_/g, '/');
json.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));
json.allowCredentials.forEach((listItem: any) => {
const fixedId = listItem.id.replace(/\_/g, '/').replace(/\-/g, '+');
listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
});
return json;
}
// From https://github.com/abergs/fido2-net-lib/blob/b487a1d47373ea18cd752b4988f7262035b7b54e/Demo/wwwroot/js/helpers.js#L34
// License: https://github.com/abergs/fido2-net-lib/blob/master/LICENSE.txt
function coerceToBase64Url(thing: any) {

View File

@ -1,5 +1,5 @@
import { getQsParam } from './common';
import { b64Decode, buildDataString } from './common-webauthn';
import { b64Decode, buildDataString, parseWebauthnJson } from './common-webauthn';
// tslint:disable-next-line
require('./webauthn.scss');
@ -63,7 +63,7 @@ function start() {
let json: any;
try {
const jsonString = b64Decode(data);
json = JSON.parse(jsonString);
json = parseWebauthnJson(jsonString);
}
catch (e) {
error('Cannot parse data.');
@ -74,15 +74,6 @@ function start() {
}
async function initWebAuthn(obj: any) {
const challenge = obj.challenge.replace(/-/g, '+').replace(/_/g, '/');
obj.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));
// fix escaping. Change this to coerce
obj.allowCredentials.forEach((listItem: any) => {
const fixedId = listItem.id.replace(/\_/g, '/').replace(/\-/g, '+');
listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
});
try {
const assertedCredential = await navigator.credentials.get({ publicKey: obj }) as PublicKeyCredential;

View File

@ -1,5 +1,5 @@
import { getQsParam } from './common';
import { b64Decode, buildDataString } from './common-webauthn';
import { b64Decode, buildDataString, parseWebauthnJson } from './common-webauthn';
// tslint:disable-next-line
require('./webauthn.scss');
@ -50,22 +50,13 @@ function start() {
try {
const jsonString = b64Decode(data);
obj = JSON.parse(jsonString);
obj = parseWebauthnJson(jsonString);
}
catch (e) {
error('Cannot parse data.');
return;
}
const challenge = obj.challenge.replace(/-/g, '+').replace(/_/g, '/');
obj.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));
// fix escaping. Change this to coerce
obj.allowCredentials.forEach((listItem: any) => {
const fixedId = listItem.id.replace(/\_/g, '/').replace(/\-/g, '+');
listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
});
stopWebAuthn = false;
if (navigator.userAgent.indexOf(' Safari/') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) {