Security Best Practices
Guidelines for securely implementing OTP-based authentication with otplib.
Secret Generation
Always use cryptographically secure random number generation. otplib's generateSecret uses a CSPRNG (Cryptographically Secure Pseudo-Random Number Generator) internally.
// UNSAFE: Predictable values
const secret = "AAAAAAAAAAAAAAAA";
const secret = "user123secret";
// UNSAFE: Weak random sources
const secret = Math.random().toString(36);
const secret = Date.now().toString();Token Verification
Constant-Time Comparison
otplib uses constant-time comparison internally to prevent timing attacks.
// UNSAFE: Vulnerable to timing attacks
if (generatedToken === userToken) {
// ...
}Rate Limiting
This library does not implement rate limiting and is focus on providing OTP functionality. Do implement rate limiting in your application to prevent brute-force attacks.
Replay Attack Prevention
otplib is a stateless library. It does not track which tokens have already been verified.
HOTP
Always increment the counter after successful verification.
if (result.valid) {
// Remember to implement a counter increment function
// to prevent replay
await updateCounter(counter + result.delta + 1);
grantAccess();
}TOTP
Consider implementing stateful tracking in your application database or cache to prevent replay attacks. Without this, a valid token can be reused multiple times within its validity window.
Other Common Vulnerabilities
Secret Exposure in Logs
// UNSAFE: Exposes secret in logs
console.log("Verifying token for secret:", secret);Large Verification Windows
// UNSAFE: Large verification windows allow replay attacks
const result = await verify({ secret, token, epochTolerance: 300 });// SAFER: Small verification windows prevent replay attacks
const result = await verify({ secret, token, epochTolerance: 30 });Further Reading
- RFC 4226 - HOTP Algorithm
- RFC 6238 - TOTP Algorithm
- OWASP Authentication Cheat Sheet
- NIST Digital Identity Guidelines