Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@simplewebauthn/server

Package Overview
Dependencies
Maintainers
1
Versions
84
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@simplewebauthn/server - npm Package Compare versions

Comparing version 4.3.0 to 4.4.0

2

dist/authentication/verifyAuthenticationResponse.d.ts

@@ -5,3 +5,3 @@ /// <reference types="node" />

credential: AuthenticationCredentialJSON;
expectedChallenge: string;
expectedChallenge: string | ((challenge: string) => boolean);
expectedOrigin: string | string[];

@@ -8,0 +8,0 @@ expectedRPID: string | string[];

@@ -56,3 +56,8 @@ "use strict";

// 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}"`);

@@ -59,0 +64,0 @@ }

@@ -24,2 +24,3 @@ "use strict";

let invalidSubjectAndIssuerError = false;
let certificateNotYetValidOrExpiredErrorMessage = undefined;
for (const rootCert of rootCertificates) {

@@ -29,4 +30,6 @@ try {

await _validatePath(certsWithRoot);
// If we successfully validated a path then there's no need to continue
// If we successfully validated a path then there's no need to continue. Reset any existing
// errors that were thrown by earlier root certificates
invalidSubjectAndIssuerError = false;
certificateNotYetValidOrExpiredErrorMessage = undefined;
break;

@@ -38,2 +41,5 @@ }

}
else if (err instanceof CertificateNotYetValidOrExpired) {
certificateNotYetValidOrExpiredErrorMessage = err.message;
}
else {

@@ -48,2 +54,5 @@ throw err;

}
else if (certificateNotYetValidOrExpiredErrorMessage) {
throw new CertificateNotYetValidOrExpired(certificateNotYetValidOrExpiredErrorMessage);
}
return true;

@@ -61,4 +70,6 @@ }

subjectCert.readCertPEM(subjectPem);
const isLeafCert = i === 0;
const isRootCert = i + 1 >= certificates.length;
let issuerPem = '';
if (i + 1 >= certificates.length) {
if (isRootCert) {
issuerPem = subjectPem;

@@ -81,3 +92,11 @@ }

if (notBefore > now || notAfter < now) {
throw new Error('Intermediate certificate is not yet valid or expired');
if (isLeafCert) {
throw new CertificateNotYetValidOrExpired(`Leaf certificate is not yet valid or expired: ${issuerPem}`);
}
else if (isRootCert) {
throw new CertificateNotYetValidOrExpired(`Root certificate is not yet valid or expired: ${issuerPem}`);
}
else {
throw new CertificateNotYetValidOrExpired(`Intermediate certificate is not yet valid or expired: ${issuerPem}`);
}
}

@@ -107,2 +126,8 @@ if (subjectCert.getIssuerString() !== issuerCert.getSubjectString()) {

}
class CertificateNotYetValidOrExpired extends Error {
constructor(message) {
super(message);
this.name = 'CertificateNotYetValidOrExpired';
}
}
//# sourceMappingURL=validateCertificatePath.js.map

@@ -8,2 +8,2 @@ /// <reference types="node" />

*/
export default function verifyAttestationWithMetadata(statement: MetadataStatement, alg: number, x5c: Buffer[] | Base64URLString[]): Promise<boolean>;
export default function verifyAttestationWithMetadata(statement: MetadataStatement, credentialPublicKey: Buffer, x5c: Buffer[] | Base64URLString[]): Promise<boolean>;

@@ -8,2 +8,4 @@ "use strict";

const validateCertificatePath_1 = __importDefault(require("../helpers/validateCertificatePath"));
const decodeCredentialPublicKey_1 = __importDefault(require("../helpers/decodeCredentialPublicKey"));
const convertCOSEtoPKCS_1 = require("../helpers/convertCOSEtoPKCS");
/**

@@ -13,5 +15,5 @@ * Match properties of the authenticator's attestation statement against expected values as

*/
async function verifyAttestationWithMetadata(statement, alg, x5c) {
async function verifyAttestationWithMetadata(statement, credentialPublicKey, x5c) {
// Make sure the alg in the attestation statement matches one of the ones specified in metadata
const statementCOSEAlgs = new Set();
const keypairCOSEAlgs = new Set();
statement.authenticationAlgorithms.forEach(algSign => {

@@ -21,9 +23,43 @@ // Convert algSign string to { kty, alg, crv }

if (algSignCOSEINFO) {
statementCOSEAlgs.add(algSignCOSEINFO.alg);
keypairCOSEAlgs.add(algSignCOSEINFO);
}
});
if (!statementCOSEAlgs.has(alg)) {
const debugAlgs = Array.from(statementCOSEAlgs).join(', ');
throw new Error(`Attestation alg "${alg}" did not match metadata auth algs [${debugAlgs}]`);
// Extract the public key's COSE info for comparison
const decodedPublicKey = decodeCredentialPublicKey_1.default(credentialPublicKey);
// Assume everything is a number because these values should be
const publicKeyCOSEInfo = {
kty: decodedPublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.kty),
alg: decodedPublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.alg),
crv: decodedPublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.crv),
};
if (!publicKeyCOSEInfo.crv) {
delete publicKeyCOSEInfo.crv;
}
/**
* Attempt to match the credential public key's algorithm to one specified in the device's
* metadata
*/
let foundMatch = false;
for (const keypairAlg of keypairCOSEAlgs) {
// Make sure algorithm and key type match
if (keypairAlg.alg === publicKeyCOSEInfo.alg && keypairAlg.kty === publicKeyCOSEInfo.kty) {
// If not an RSA keypair then make sure curve numbers match too
if ((keypairAlg.kty === convertCOSEtoPKCS_1.COSEKTY.EC2 || keypairAlg.kty === convertCOSEtoPKCS_1.COSEKTY.OKP)
&& keypairAlg.crv === publicKeyCOSEInfo.crv) {
foundMatch = true;
}
else {
// We've matched an RSA public key's properties
foundMatch = true;
}
}
if (foundMatch) {
break;
}
}
// Make sure the public key is one of the allowed algorithms
if (!foundMatch) {
const debugAlgs = Array.from(keypairCOSEAlgs).join(', ');
throw new Error(`Public key algorithm ${publicKeyCOSEInfo} did not match any metadata algorithms [${debugAlgs}]`);
}
try {

@@ -33,3 +69,3 @@ await validateCertificatePath_1.default(x5c.map(convertCertBufferToPEM_1.default), statement.attestationRootCertificates.map(convertCertBufferToPEM_1.default));

catch (err) {
throw new Error(`Could not validate certificate path with any metadata root certificates`);
throw new Error(`Could not validate certificate path with any metadata root certificates: ${err.message}`);
}

@@ -36,0 +72,0 @@ return true;

@@ -209,3 +209,3 @@ "use strict";

try {
await verifyAttestationWithMetadata_1.default(statement, alg, x5c);
await verifyAttestationWithMetadata_1.default(statement, credentialPublicKey, x5c);
}

@@ -212,0 +212,0 @@ catch (err) {

@@ -81,3 +81,3 @@ "use strict";

try {
await verifyAttestationWithMetadata_1.default(statement, alg, x5c);
await verifyAttestationWithMetadata_1.default(statement, credentialPublicKey, x5c);
}

@@ -84,0 +84,0 @@ catch (err) {

@@ -18,3 +18,3 @@ "use strict";

async function verifyAttestationAndroidSafetyNet(options) {
const { attStmt, clientDataHash, authData, aaguid, rootCertificates, verifyTimestampMS = true, } = options;
const { attStmt, clientDataHash, authData, aaguid, rootCertificates, verifyTimestampMS = true, credentialPublicKey, } = options;
const { response, ver } = attStmt;

@@ -76,5 +76,3 @@ if (!ver) {

try {
// Convert from alg in JWT header to a number in the metadata
const alg = HEADER.alg === 'RS256' ? -257 : -99999;
await verifyAttestationWithMetadata_1.default(statement, alg, HEADER.x5c);
await verifyAttestationWithMetadata_1.default(statement, credentialPublicKey, HEADER.x5c);
}

@@ -81,0 +79,0 @@ catch (err) {

@@ -92,3 +92,3 @@ "use strict";

try {
await verifyAttestationWithMetadata_1.default(statement, alg, x5c);
await verifyAttestationWithMetadata_1.default(statement, credentialPublicKey, x5c);
}

@@ -95,0 +95,0 @@ catch (err) {

@@ -6,3 +6,3 @@ /// <reference types="node" />

credential: RegistrationCredentialJSON;
expectedChallenge: string | ChallengeVerifier;
expectedChallenge: string | ((challenge: string) => boolean);
expectedOrigin: string | string[];

@@ -13,3 +13,2 @@ expectedRPID?: string | string[];

};
export declare type ChallengeVerifier = (challenge: string) => boolean;
/**

@@ -16,0 +15,0 @@ * Verify that the user has legitimately completed the registration process

@@ -12,12 +12,1 @@ /**

export declare const GlobalSign_Root_CA = "-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\nA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\nb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\nMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\nYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\naWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\njc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\nxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\n1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\nsnUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\nU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\n9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\nBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\nAQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\nyj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\n38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\nAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\nDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\nHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----\n";
/**
* GlobalSign R2
*
* Downloaded from https://pki.goog/repo/certs/gsr2.pem
*
* Valid until 2021-12-15 @ 00:00 PST
*
* SHA256 Fingerprint
* 69:E2:D0:6C:30:F3:66:16:61:65:E9:1D:68:D1:CE:E5:CC:47:58:4A:80:22:7E:76:66:60:86:C0:10:72:41:EB
*/
export declare const GlobalSign_R2 = "-----BEGIN CERTIFICATE-----\nMIIDvDCCAqSgAwIBAgINAgPk9GHsmdnVeWbKejANBgkqhkiG9w0BAQUFADBMMSAw\nHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs\nU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0wNjEyMTUwODAwMDBaFw0yMTEy\nMTUwODAwMDBaMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMw\nEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMIIBIjANBgkq\nhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAps8kDr4ubyiZRULEqz4hVJsL03+EcPoS\ns8u/h1/Gf4bTsjBc1v2t8Xvc5fhglgmSEPXQU977e35ziKxSiHtKpspJpl6op4xa\nEbx6guu+jOmzrJYlB5dKmSoHL7Qed7+KD7UCfBuWuMW5Oiy81hK561l94tAGhl9e\nSWq1OV6INOy8eAwImIRsqM1LtKB9DHlN8LgtyyHK1WxbfeGgKYSh+dOUScskYpEg\nvN0L1dnM+eonCitzkcadG6zIy+jgoPQvkItN+7A2G/YZeoXgbfJhE4hcn+CTClGX\nilrOr6vV96oJqmC93Nlf33KpYBNeAAHJSvo/pOoHAyECjoLKA8KbjwIDAQABo4Gc\nMIGZMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSb\n4gdXZxwewGoG3lm0mi3f3BmGLjAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f\n3BmGLjA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0\nL3Jvb3QtcjIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQANeX81Z1YqDIs4EaLjG0qP\nOxIzaJI/y4kiRj3a+y3KOx74clIkLuMgi/9/5iv/n+1LyhGU9g7174slbzJOPbSp\np1eT19ST2mYbdgTLx/hm3tTLoHIY/w4ZbnQYwfnPwAG4RefnEFYPQJmpD+Wh8BJw\nBgtm2drTale/T6NBwmwnEFunfaMfMX3g6IBrx7VKnxIkJh/3p190WveLKgl9n7i5\nSWce/4woPimEn9WfEQWRvp6wKhaCKFjuCMuulEZusoOUJ4LfJnXxcuQTgIrSnwI7\nKfSSjsd42w3lX1fbgJp7vPmLM6OBRvAXuYRKTFqMAWbb7OaGIEE+cbxY6PDepnva\n-----END CERTIFICATE-----\n";
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GlobalSign_R2 = exports.GlobalSign_Root_CA = void 0;
exports.GlobalSign_Root_CA = void 0;
/**

@@ -36,35 +36,2 @@ * GlobalSign Root CA

`;
/**
* GlobalSign R2
*
* Downloaded from https://pki.goog/repo/certs/gsr2.pem
*
* Valid until 2021-12-15 @ 00:00 PST
*
* SHA256 Fingerprint
* 69:E2:D0:6C:30:F3:66:16:61:65:E9:1D:68:D1:CE:E5:CC:47:58:4A:80:22:7E:76:66:60:86:C0:10:72:41:EB
*/
exports.GlobalSign_R2 = `-----BEGIN CERTIFICATE-----
MIIDvDCCAqSgAwIBAgINAgPk9GHsmdnVeWbKejANBgkqhkiG9w0BAQUFADBMMSAw
HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs
U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0wNjEyMTUwODAwMDBaFw0yMTEy
MTUwODAwMDBaMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMw
EQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAps8kDr4ubyiZRULEqz4hVJsL03+EcPoS
s8u/h1/Gf4bTsjBc1v2t8Xvc5fhglgmSEPXQU977e35ziKxSiHtKpspJpl6op4xa
Ebx6guu+jOmzrJYlB5dKmSoHL7Qed7+KD7UCfBuWuMW5Oiy81hK561l94tAGhl9e
SWq1OV6INOy8eAwImIRsqM1LtKB9DHlN8LgtyyHK1WxbfeGgKYSh+dOUScskYpEg
vN0L1dnM+eonCitzkcadG6zIy+jgoPQvkItN+7A2G/YZeoXgbfJhE4hcn+CTClGX
ilrOr6vV96oJqmC93Nlf33KpYBNeAAHJSvo/pOoHAyECjoLKA8KbjwIDAQABo4Gc
MIGZMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSb
4gdXZxwewGoG3lm0mi3f3BmGLjAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f
3BmGLjA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0
L3Jvb3QtcjIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQANeX81Z1YqDIs4EaLjG0qP
OxIzaJI/y4kiRj3a+y3KOx74clIkLuMgi/9/5iv/n+1LyhGU9g7174slbzJOPbSp
p1eT19ST2mYbdgTLx/hm3tTLoHIY/w4ZbnQYwfnPwAG4RefnEFYPQJmpD+Wh8BJw
Bgtm2drTale/T6NBwmwnEFunfaMfMX3g6IBrx7VKnxIkJh/3p190WveLKgl9n7i5
SWce/4woPimEn9WfEQWRvp6wKhaCKFjuCMuulEZusoOUJ4LfJnXxcuQTgIrSnwI7
KfSSjsd42w3lX1fbgJp7vPmLM6OBRvAXuYRKTFqMAWbb7OaGIEE+cbxY6PDepnva
-----END CERTIFICATE-----
`;
//# sourceMappingURL=android-safetynet.js.map

@@ -52,3 +52,3 @@ "use strict";

identifier: 'android-safetynet',
certificates: [android_safetynet_1.GlobalSign_R2, android_safetynet_1.GlobalSign_Root_CA],
certificates: [android_safetynet_1.GlobalSign_Root_CA],
});

@@ -55,0 +55,0 @@ settingsService.setRootCertificates({

{
"name": "@simplewebauthn/server",
"version": "4.3.0",
"version": "4.4.0",
"description": "SimpleWebAuthn for Servers",

@@ -62,3 +62,3 @@ "main": "dist/index.js",

},
"gitHead": "717b7037f58ff18003309e2c1f05f5a2f7036c2d",
"gitHead": "4a8fb255d4fd6fbc146dedf0a2efc938b99f5973",
"devDependencies": {

@@ -65,0 +65,0 @@ "@types/cbor": "^5.0.1",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc