Facebook Pixel

Password Security Roadmap for Node.js

A step-by-step roadmap for password security in a Node.js app.

Password Security Roadmap for Node.js

A roadmap keeps your password security focused. Here is the path from basics to production-ready.

Step 1: Never Store Plain Text

Hash with bcrypt or argon2 before saving. No exceptions. Even for test data. This is the foundation.

Step 2: Pick a Hashing Algorithm

bcrypt with 10-12 rounds for existing or simple projects. argon2id for new projects with no constraints. PBKDF2 only if you need a standard built into Node.

Step 3: Use a Salt

bcrypt and argon2 handle salting automatically. Do not roll your own. A salt ensures two users with the same password get different hashes.

Step 4: Hash in a pre('save') Hook

userSchema.pre('save', async function(next) {
  if (!this.isModified('passwordHash')) return next();
  this.passwordHash = await bcrypt.hash(this.passwordHash, 10);
  next();
});

Check isModified so profile updates do not rehash.

Step 5: Handle Updates

For findByIdAndUpdate, hash in a pre('findOneAndUpdate') hook or in the controller. Updates bypass pre('save') by default.

Step 6: Mark passwordHash With select: false

Excluded from find queries by default. Use .select('+passwordHash') only when needed (e.g., for login).

Step 7: Use a Serializer

Never include passwordHash in responses. Use a toUserDTO function that picks only the safe fields. Defense in depth.

Step 8: Never Log Passwords or Hashes

Filter sensitive fields from logs. Use a logger that redacts known fields. A debug log accidentally containing a password is a leak.

Step 9: Validate Password Strength

Minimum 8 characters. Encourage passphrases. Reject common passwords (haveibeenpwned API). Do not enforce arbitrary complexity rules.

Step 10: Rate Limit Login

5 attempts per 15 minutes per IP and per email. Prevents brute force. Lock the account temporarily after too many failures.

Step 11: Use HTTPS

Never send passwords over HTTP. HTTPS is non-negotiable. Use Let's Encrypt for free certs.

Step 12: Implement Password Reset

Generate a random token, store its hash with a 15-min expiry, email a link, verify on reset, hash the new password, invalidate the token. Rate limit the request endpoint.

Step 13: Invalidate Sessions on Password Change

Bump a tokenVersion field on the user. The auth middleware checks that the JWT's tokenVersion matches. After a change, old JWTs are rejected.

Step 14: Use httpOnly Cookies for JWT

Store JWT in an httpOnly, secure, sameSite cookie. Scripts cannot read it. Defense in depth for XSS.

Step 15: Notify Users of Changes

Send an email when the password is changed. If the user did not change it, they can take action.

The Takeaway

The password security roadmap: never plain text, pick an algorithm (bcrypt or argon2), use a salt, hash in a pre('save') hook, handle updates, mark with select: false, use a serializer, never log passwords, validate strength, rate limit login, use HTTPS, implement password reset, invalidate sessions on change, use httpOnly cookies for JWT, and notify users of changes.

Never plain text, pick an algorithm (bcrypt or argon2), use a salt, hash in a pre('save') hook, handle updates, mark with select: false, use a serializer, never log passwords, validate strength, rate limit login, use HTTPS, implement password reset, invalidate sessions on change, use httpOnly cookies, and notify users.

Never store plain text. Hash with bcrypt or argon2 before saving. No exceptions. Without this, every other step is wasted. This is the foundation.

After basic auth works and you have hashing in place. Reset depends on hashing the new password and sending emails. Implement it before launch so users can recover from forgotten passwords.

Bump a tokenVersion field on the user. The auth middleware checks that the JWT's tokenVersion matches the user's current one. After a change, old JWTs are rejected and the user must log in again.

If an attacker changes the password, the user gets an email they did not expect. They can take action (reset the password, contact support). Silence on password change is a security hole.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.