Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
github.com/fxamacker/webauthn
This WebAuthn server library provides registration and authentication for clients using FIDO2 keys, FIDO U2F keys, TPM, and etc.
It's decoupled from net/http
and doesn't force you to use a framework. So it's easy to use in existing projects.
It's modular so you only import the attestation formats you need. This helps your software avoid bloat.
Six attestation formats are provided: fidou2f, androidkeystore, androidsafetynet, packed, tpm, and none.
It doesn't import unreliable packages. It imports fxamacker/cbor because it doesn't crash and it's the most well-tested CBOR library available (v1.5 has 375+ tests and passed 3+ billion execs in coverage-guided fuzzing).
A demo webapp (webauthn-demo) shows how to use this library with a security token like the YubiKey pictured here.
WebAuthn (Web Authentication) is a W3C web standard for authenticating users to web-based apps and services. It's a core component of FIDO2, the successor of FIDO U2F legacy protocol.
fxamacker/webauthn is designed to be:
net/http
and is not a frameworkIt's functional enough to demo but unit tests need work. Expired certs embedded in test data can make unit tests to fail. A temporary workaround is to fake datetime when running unit tests locally until expired test data are replaced.
go get github.com/fxamacker/webauthn
See API docs.
Create assertion or attestation options:
NewAssertionOptions creates PublicKeyCredentialRequestOptions. NewAttestationOptions creates PublicKeyCredentialCreationOptions. Config represents Relying Party settings used to create those options. Config is initialized at startup and used throughout the program. User contains user data for which the Relying Party requests attestation or assertion.
func NewAssertionOptions(config *Config, user *User) (*PublicKeyCredentialRequestOptions, error)
func NewAttestationOptions(config *Config, user *User) (*PublicKeyCredentialCreationOptions, error)
Parse assertion or attestation:
ParseAssertion returns parsed PublicKeyCredentialAssertion. ParseAttestation returns parsed PublicKeyCredentialAttestation.
func ParseAssertion(r io.Reader) (*PublicKeyCredentialAssertion, error)
func ParseAttestation(r io.Reader) (*PublicKeyCredentialAttestation, error)
Verify assertion or attestation:
VerifyAssertion verifies PublicKeyCredentialAssertion, returned by ParseAssertion. AssertionExpectedData contains data needed to verify an assertion.
VerifyAttestation verifies PublicKeyCredentialAttestation, returned by ParseAttestation. AttestationExpectedData contains data needed to verify an attestation before registering a new credential. VerifyAttestation returns attestation type and attestation trust path. Library users need to assess the attestation trustworthiness by verifying that attestation type is acceptable and trust path can be trusted.
func VerifyAssertion(credentialAssertion *PublicKeyCredentialAssertion, expected *AssertionExpectedData) error
func VerifyAttestation(credentialAttestation *PublicKeyCredentialAttestation, expected *AttestationExpectedData) (attType AttestationType, trustPath interface{}, err error)
See examples.
Initialize Relying Party config:
// cfg is initialized at startup and used throughout the program to create attestation and assertion options.
cfg := &webauthn.Config{
RPID: "localhost",
RPName: "WebAuthn local host",
Timeout: uint64(30000),
ChallengeLength: 64,
AuthenticatorAttachment: webauthn.AuthenticatorPlatform,
ResidentKey: webauthn.ResidentKeyPreferred,
UserVerification: webauthn.UserVerificationPreferred,
Attestation: webauthn.AttestationDirect,
CredentialAlgs: []int{webauthn.COSEAlgES256, webauthn.COSEAlgES384, webauthn.COSEAlgES512},
}
err := cfg.Valid()
if err != nil {
return err
}
Create attestation options:
// user contains user data for which the Relying Party requests attestation or assertion.
user := &webauthn.User{
ID: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
Name: "Jane Doe",
DisplayName: "Jane",
}
creationOptions, err := webauthn.NewAttestationOptions(cfg, user)
if err != nil {
return err
}
creationOptionsJSON, err := json.Marshal(creationOptions)
if err != nil {
return err
}
// Save user and creationOptions in session to verify attestation later.
// Send creationOptionsJSON to web client, which passes it to navigator.credentials.create().
Parse and verify attestation:
// Parse PublicKeyCredentialAttestation returned by navigator.credentials.create().
credentialAttestation, err := webauthn.ParseAttestation(r)
if err != nil {
return err
}
// Create AttestationExpectedData object from session's user and creationOptions.
expected := &webauthn.AttestationExpectedData{
Origin: "https://localhost:8443",
RPID: "localhost",
CredentialAlgs: []int{webauthn.COSEAlgES256, webauthn.COSEAlgES384, webauthn.COSEAlgES512},
Challenge: "33EHav-jZ1v9qwH783aU-j0ARx6r5o-YHh-wd7C6jPbd7Wh6ytbIZosIIACehwf9-s6hXhySHO-HHUjEwZS29w",
UserVerification: webauthn.UserVerificationPreferred,
}
attType, trustPath, err := webauthn.VerifyAttestation(credentialAttestation, expected)
if err != nil {
return err
}
// Verify that attType is acceptable and trustPath can be trusted.
// Save user info, credential id, algorithm, public key, and counter to persistent store.
// User is registered.
Create assertion options:
// user contains user data for which the Relying Party requests attestation or assertion.
user := &webauthn.User{
ID: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
Name: "Jane Doe",
DisplayName: "Jane",
CredentialIDs: [][]byte{
[]byte{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26},
},
}
requestOptions, err := webauthn.NewAssertionOptions(cfg, user)
if err != nil {
return err
}
requestOptionsJSON, err := json.Marshal(requestOptions)
if err != nil {
return err
}
// Save user and requestOptions in session to verify assertion later.
// Send requestOptionsJSON to web client, which passes it to navigator.credentials.get().
Parse and verify assertion:
// Parse PublicKeyCredentialAssertion returned by navigator.credentials.get().
credentialAssertion, err := webauthn.ParseAssertion(r)
if err != nil {
return err
}
// Create AssertionExpectedData object from session's user and requestOptions.
expected := &webauthn.AssertionExpectedData{
Origin: "https://localhost:8443",
RPID: "localhost",
Challenge: "eaTyUNnyPDDdK8SNEgTEUvz1Q8dylkjjTimYd5X7QAo-F8_Z1lsJi3BilUpFZHkICNDWY8r9ivnTgW7-XZC3qQ",
UserVerification: webauthn.UserVerificationPreferred,
UserID: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
UserCredentialIDs: [][]byte{
[]byte{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26},
},
PrevCounter: uint32(362),
Credential: credential,
}
err = webauthn.VerifyAssertion(credentialAssertion, expected)
if err != nil {
return err
}
// Update counter in persistent store.
// User is authenticated.
This library doesn't support:
Security fixes are provided for the latest released version.
To report security vulnerabilities, please email faye.github@gmail.com and allow time for the problem to be resolved before reporting it to the public.
Montgomery Edwards⁴⁴⁸ (x448) for updating README.md and filing helpful issues.
Ackermann Yuriy (herrjemand) for his extensive tutorials on WebAuthn/FIDO2.
Adam Powers (apowers313) for fido2-lib because that pointed me in the direction of separating WebAuthn functionality from any networking protocol.
This library uses attestation and assertion test data from both herrjemand and apowers313.
Copyright 2019-present Faye Amacker
fxamacker/webauthn is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
FAQs
Unknown package
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
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.