Improve WebAuthn error detection for invalid data (#946)
This commit is contained in:
parent
2392d34ed8
commit
d71d0d9af6
|
@ -27,6 +27,20 @@ export function b64Decode(str: string) {
|
||||||
}).join(''));
|
}).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
|
// 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
|
// License: https://github.com/abergs/fido2-net-lib/blob/master/LICENSE.txt
|
||||||
function coerceToBase64Url(thing: any) {
|
function coerceToBase64Url(thing: any) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { getQsParam } from './common';
|
import { getQsParam } from './common';
|
||||||
import { b64Decode, buildDataString } from './common-webauthn';
|
import { b64Decode, buildDataString, parseWebauthnJson } from './common-webauthn';
|
||||||
|
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
require('./webauthn.scss');
|
require('./webauthn.scss');
|
||||||
|
@ -63,7 +63,7 @@ function start() {
|
||||||
let json: any;
|
let json: any;
|
||||||
try {
|
try {
|
||||||
const jsonString = b64Decode(data);
|
const jsonString = b64Decode(data);
|
||||||
json = JSON.parse(jsonString);
|
json = parseWebauthnJson(jsonString);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
error('Cannot parse data.');
|
error('Cannot parse data.');
|
||||||
|
@ -74,15 +74,6 @@ function start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initWebAuthn(obj: any) {
|
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 {
|
try {
|
||||||
const assertedCredential = await navigator.credentials.get({ publicKey: obj }) as PublicKeyCredential;
|
const assertedCredential = await navigator.credentials.get({ publicKey: obj }) as PublicKeyCredential;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { getQsParam } from './common';
|
import { getQsParam } from './common';
|
||||||
import { b64Decode, buildDataString } from './common-webauthn';
|
import { b64Decode, buildDataString, parseWebauthnJson } from './common-webauthn';
|
||||||
|
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
require('./webauthn.scss');
|
require('./webauthn.scss');
|
||||||
|
@ -50,22 +50,13 @@ function start() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const jsonString = b64Decode(data);
|
const jsonString = b64Decode(data);
|
||||||
obj = JSON.parse(jsonString);
|
obj = parseWebauthnJson(jsonString);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
error('Cannot parse data.');
|
error('Cannot parse data.');
|
||||||
return;
|
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;
|
stopWebAuthn = false;
|
||||||
|
|
||||||
if (navigator.userAgent.indexOf(' Safari/') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) {
|
if (navigator.userAgent.indexOf(' Safari/') !== -1 && navigator.userAgent.indexOf('Chrome') === -1) {
|
||||||
|
|
Loading…
Reference in New Issue