← Back to Blog

Password Security Best Practices for Developers

Password breaches cost companies millions and destroy user trust. As developers, we have a responsibility to handle passwords securely. One mistake can expose thousands of users to identity theft and account takeover.

⚠️ Critical Rule: Never, ever store passwords in plain text. This should go without saying, but breaches still happen because developers ignore this fundamental rule.

The Golden Rules of Password Security

1. Always Hash, Never Store Plain Text

Passwords must be hashed using modern algorithms before storage. If your database gets breached, hashed passwords are useless to attackers without the ability to reverse them.

2. Use Proper Hashing Algorithms

Not all hashing is created equal:

Password Hashing Implementation

Using bcrypt (Node.js)

const bcrypt = require('bcrypt');
const saltRounds = 12;

// Hashing a password
async function hashPassword(plainPassword) {
    const hash = await bcrypt.hash(plainPassword, saltRounds);
    return hash;
}

// Verifying a password
async function verifyPassword(plainPassword, hash) {
    const match = await bcrypt.compare(plainPassword, hash);
    return match;  // true or false
}

Using Argon2 (Python)

from argon2 import PasswordHasher

ph = PasswordHasher()

# Hash password
hash = ph.hash("my_password")

# Verify password
try:
    ph.verify(hash, "my_password")
    print("Password correct")
except:
    print("Password incorrect")

Password Generation Best Practices

Strong passwords are the first line of defense. They should be:

🔐 Generate Secure Passwords →

Password Requirements

Set sensible requirements:

// Good password policy
- Minimum 12 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
- No common passwords (check against breach databases)
Don't go overboard: Requirements like "must contain emoji" or "rotate every 30 days" reduce security by encouraging password reuse and predictable patterns.

Salting: Why It Matters

A salt is random data added to passwords before hashing. This prevents:

Example without salt:

// Two users, same password
User1: "password123" → hash: 5f4dcc3b5aa765d61d8327deb882cf99
User2: "password123" → hash: 5f4dcc3b5aa765d61d8327deb882cf99
// ⚠️ Attacker sees they're identical!

Example with salt:

// Two users, same password, different salts
User1: "password123" + salt1 → hash: a7f5c9d2e...
User2: "password123" + salt2 → hash: b3e8d1a4f...
// ✅ Hashes look completely different

Password Storage Architecture

Your database should store:

users table:
- id
- username
- email
- password_hash (NOT plain text!)
- password_salt (if not using bcrypt/argon2)
- password_updated_at
- failed_login_attempts
- account_locked_until

Preventing Brute Force Attacks

Rate Limiting

Limit login attempts to prevent automated attacks:

Exponential Backoff

Failed attempts | Delay before next attempt
1               | 0 seconds
2               | 2 seconds
3               | 4 seconds
4               | 8 seconds
5               | 16 seconds (+ CAPTCHA)

Multi-Factor Authentication (MFA)

Passwords alone aren't enough. Implement MFA using:

Password Reset Security

Password resets are a common attack vector. Secure them properly:

  1. Use time-limited tokens: Expire after 15-60 minutes
  2. One-time use: Invalidate token after successful reset
  3. Don't reveal if email exists: Always show "If email exists, check your inbox"
  4. Require email verification: Send reset link, don't show reset form directly
  5. Invalidate old sessions: Log out all devices after password change
// Secure password reset flow
1. User requests reset
2. Generate random token (32+ bytes)
3. Store token hash + expiry in database
4. Send email with reset link
5. User clicks link, validates token
6. Allow password change
7. Invalidate token
8. Log out all sessions
9. Send confirmation email

Common Security Mistakes

❌ Sending Passwords via Email

Email is not secure. Never send passwords (or password reset links without expiry) via email.

❌ Security Questions

They're just passwords with publicly guessable answers. Don't use them. If required, treat them as password-equivalent secrets.

❌ Client-Side Only Validation

Always validate and hash on the server. Client-side validation can be bypassed easily.

❌ Password Hints

These make passwords easier to guess. Don't implement them.

❌ Forced Password Rotation

Research shows this reduces security by encouraging predictable patterns (Password1, Password2, etc.). Only require changes after suspected compromise.

Testing Password Security

Check passwords against breach databases:

Tools for Secure Password Management

Use our Password Generator to create cryptographically secure passwords with customizable rules. Also check out our Hash Generator to understand different hashing algorithms.

Conclusion

Password security isn't optional - it's a fundamental responsibility. Use modern hashing algorithms, implement MFA, prevent brute force attacks, and never cut corners. Your users trust you with their security. Don't let them down.

← Back to Blog