Skip to content

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.

typescript
// 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.

typescript
// 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. See the Replay Protection (HOTP) guide for examples.

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. See the Replay Protection guide for implementation details and examples.

Other Common Vulnerabilities

Secret Exposure in Logs

typescript
// UNSAFE: Exposes secret in logs
console.log("Verifying token for secret:", secret);

Large Verification Windows

typescript
// UNSAFE: Large verification windows allow replay attacks
const result = await verify({ secret, token, epochTolerance: 300 });
typescript
// SAFER: Small verification windows prevent replay attacks
const result = await verify({ secret, token, epochTolerance: 30 });

Further Reading

Released under the MIT License.