
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@sourceregistry/node-webauthn
Advanced tools
Production-focused TypeScript helpers for WebAuthn registration and authentication flows in Node.js.
TypeScript helpers for WebAuthn registration and authentication with dedicated server and client entrypoints.
npm install @sourceregistry/node-webauthn
npx jsr add @sourceregistry/node-webauthn
import createWebAuth from "@sourceregistry/node-webauthn/server";
import createWebAuthClient from "@sourceregistry/node-webauthn/client";
@sourceregistry/node-webauthn re-exports the server entry:
import createWebAuth from "@sourceregistry/node-webauthn";
import createWebAuth from "@sourceregistry/node-webauthn/server";
import createWebAuthClient from "@sourceregistry/node-webauthn/client";
import {generateKeyPairSync} from "node:crypto";
const {privateKey, publicKey} = generateKeyPairSync("ec", {namedCurve: "P-256"});
const server = createWebAuth({
keyPair: {
kid: "main",
private_key: privateKey,
public_key: publicKey
},
issuer: "https://auth.example.com",
rpId: "example.com",
rpName: "Example"
});
const client = createWebAuthClient();
const registrationOptions = server.createRegistrationOptions({
user: {
id: server.toBase64Url("user-123"),
name: "user@example.com",
displayName: "Example User"
}
});
const credential = await client.startRegistration(registrationOptions);
const parsed = server.verifyRegistrationResponse({
expected_challenge: registrationOptions.challenge,
credential_id: credential.id,
client_data_json: credential.client_data_json,
attestation_object: credential.attestation_object,
transports: credential.transports,
client_extension_results: credential.client_extension_results,
origin: "https://example.com",
rp_id: "example.com",
expected_algorithms: registrationOptions.pubKeyCredParams.map(item => item.alg)
});
@sourceregistry/node-webauthn
Re-exports the server entry.@sourceregistry/node-webauthn/server
Node.js option building, ceremony token, and verification helpers.@sourceregistry/node-webauthn/client
Browser helpers for JSON conversion, WebAuthn calls, and credential serialization.| Area | Status | Notes |
|---|---|---|
| Server-generated registration/authentication options | Strong | createRegistrationOptions(...) and createAuthenticationOptions(...) are the intended entrypoints. |
clientDataJSON validation | Strong | Checks ceremony type, challenge, origin allowlist, rejects unsupported cross-origin ceremonies, and normalizes malformed JSON into stable library errors. |
| Authenticator data parsing | Strong | Parses RP ID hash, flags, counters, attested credential data, and extension data. |
| Authentication assertion verification | Strong | Verifies signature, RP/appid hash, optional credential binding, UP/UV policy, counter progression, and allowed client extensions. |
| Registration verification core | Strong | Verifies RP ID hash, credential binding, requested algorithm policy, and attestation dispatch. |
| Attestation format coverage | Broad | Supports none, packed, fido-u2f, apple, android-key, android-safetynet, and tpm. |
| Attestation trust policy | Good | Supports none, permissive, and strict trust modes plus trust anchors, metadata hooks, CA/key-usage checks for issuing certs, and exact leaf pinning. |
| Extension support | Partial | Practical subset today: credProps, appid, appidExclude, and largeBlob. |
| Metadata / revocation | Partial | Metadata hooks exist, but there is no built-in FIDO MDS integration or revocation pipeline yet. |
| Cross-origin / advanced browser edge cases | Limited | Cross-origin ceremonies are intentionally rejected for now. |
| Full spec-tight attestation semantics | Partial | Some format-specific policy checks are still lighter than full ecosystem-grade verification. |
Practical summary:
createWebAuth(config)Creates a reusable server helper with:
generateChallenge(bytes?)createRegistrationOptions(input)createAuthenticationOptions(input)signRegistration(payload)verifyRegistration(token)signAuthentication(payload)verifyAuthentication(token)parseRegistration(input)verifyRegistrationResponse(input)verifyAuthenticationResponse(input)createRegistrationOptions(input)Returns JSON-safe registration options for the client helper.
createAuthenticationOptions(input)Returns JSON-safe authentication options for the client helper.
verifyRegistrationResponse(input)Validates:
Supported attestation formats:
nonepackedfido-u2fappleandroid-keyandroid-safetynettpmAttestation support status:
| Format | Status | Notes |
|---|---|---|
none | Strong | Suitable default for easy deployment. |
packed | Strong | Supports self attestation and certificate-backed validation with optional trust anchors. |
fido-u2f | Strong | Verified with optional trust anchors. |
apple | Good | Verifies Apple nonce extension and credential public-key binding. |
android-key | Partial | Core verification is present, but Android authorization-list policy checks are not exhaustive yet. |
android-safetynet | Partial | Verifies JWS, nonce, timestamp, and CTS profile, but ecosystem trust/revocation remains lightweight. |
tpm | Partial | Core certInfo / pubArea validation is present, but TPM certificate/profile checks are not exhaustive yet. |
Registration results include:
credential_idpublic_keyaaguidcounterattestation_formatattestation_typeattestation_trustedattestation_policy_acceptedmetadata_statusverifyAuthenticationResponse(input)Validates:
credential_id and expected_credential_id are suppliedTypical usage:
const result = server.verifyAuthenticationResponse({
expected_challenge: publicKey.challenge,
credential_id: credential.id,
expected_credential_id: storedCredential.credential_id,
client_data_json: credential.client_data_json,
authenticator_data: credential.authenticator_data,
signature: credential.signature,
origin: "https://example.com",
rp_id: "example.com",
public_key: storedCredential.public_key,
previous_counter: storedCredential.counter
});
createWebAuthClient()Creates browser helpers with:
toCreationOptions(json)toRequestOptions(json)startRegistration(json)startAuthentication(json)serializeRegistrationCredential(credential)serializeAuthenticationCredential(credential)toBase64Url(value)fromBase64Url(value)Server begin step:
const publicKey = server.createRegistrationOptions({
user: {
id: server.toBase64Url("user-123"),
name: "user@example.com",
displayName: "Example User"
}
});
Client step:
const credential = await client.startRegistration(publicKey);
Server finish step:
const parsed = server.verifyRegistrationResponse({
expected_challenge: publicKey.challenge,
credential_id: credential.id,
client_data_json: credential.client_data_json,
attestation_object: credential.attestation_object,
transports: credential.transports,
client_extension_results: credential.client_extension_results,
origin: "https://example.com",
rp_id: "example.com",
expected_algorithms: publicKey.pubKeyCredParams.map(item => item.alg)
});
Simple format allowlist:
const server = createWebAuth({
keyPair,
rpId: "example.com",
rpName: "Example",
attestation: {
allowed_formats: ["none", "packed"]
}
});
Strict trust:
const server = createWebAuth({
keyPair,
rpId: "example.com",
rpName: "Example",
attestation: {
allowed_formats: ["packed", "tpm"],
trust_mode: "strict",
trust_anchors: [rootCertificatePem]
}
});
Metadata-backed policy:
const server = createWebAuth({
keyPair,
rpId: "example.com",
rpName: "Example",
attestation: {
allowed_formats: ["android-key", "tpm"],
metadata_provider: {
getEntry({format}) {
if (format === "android-key") {
return {status: "trusted", trusted: true};
}
return null;
}
}
}
});
const server = createWebAuth({
keyPair,
rpId: "example.com",
rpName: "Example",
extensions: {
allowed_registration_extensions: ["credProps"],
allowed_authentication_extensions: ["appid", "largeBlob"]
}
});
The remaining work is intentionally small and incremental so the API can stay easy to use.
android-key verification with stronger authorization-list checks from the Android key attestation extension.tpm verification with more complete certificate/profile validation and TPM-specific policy checks.android-safetynet trust handling with clearer certificate-policy validation and optional revocation hooks.metadata_provider style trust model.trust_mode, trust_anchors, and metadata_provider.FAQs
Production-focused TypeScript helpers for WebAuthn registration and authentication flows in Node.js.
The npm package @sourceregistry/node-webauthn receives a total of 409 weekly downloads. As such, @sourceregistry/node-webauthn popularity was classified as not popular.
We found that @sourceregistry/node-webauthn demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.