Back to Learning Center
criticalA07:2021CWE-287CWE-384CWE-613CWE-521

Broken Authentication

Broken authentication is one of the most critical security vulnerabilities in web applications. When authentication mechanisms are flawed, attackers can compromise passwords, session tokens, or exploit implementation flaws to assume other users' identities—temporarily or permanently.

What is Broken Authentication?

Broken authentication refers to weaknesses in how applications verify user identity. This includes:

  • Weak password policies allowing simple passwords
  • Credential stuffing and brute force attacks
  • Session fixation and hijacking
  • Insecure session management
  • Missing multi-factor authentication
  • Exposed session IDs in URLs

Common Attack Vectors

Credential Stuffing

Attackers use lists of compromised credentials from data breaches to attempt logins. Since users often reuse passwords across sites, this attack is highly effective.

python
# Attacker's credential stuffing script
import requests

with open('leaked_credentials.txt') as f:
    for line in f:
        email, password = line.strip().split(':')
        response = requests.post('https://target.com/login', 
            data={'email': email, 'password': password})
        if 'Welcome' in response.text:
            print(f'[+] Valid: {email}:{password}')

Session Fixation

The attacker sets a known session ID before the user authenticates. After the user logs in, the attacker uses the same session ID to access their account.

html
<!-- Attacker sends victim this link -->
<a href="https://bank.com/login?sessionid=ATTACKERKNOWNID">
  Click here to claim your prize!
</a>

<!-- Victim logs in, session ID stays the same -->
<!-- Attacker now uses ATTACKERKNOWNID to access victim's account -->

JWT Vulnerabilities

JSON Web Tokens (JWTs) are commonly used for authentication but have several known vulnerabilities:

javascript
// Vulnerable: Server accepts 'none' algorithm
const header = {
  "alg": "none",  // No signature verification!
  "typ": "JWT"
};

// Attacker modifies payload
const payload = {
  "sub": "admin",  // Changed from 'user'
  "role": "admin"  // Escalated privileges
};

// Token without signature is accepted
const token = base64(header) + '.' + base64(payload) + '.';

Password Reset Flaws

Insecure password reset mechanisms can allow attackers to take over accounts:

javascript
// Vulnerable: Predictable reset token
app.post('/forgot-password', (req, res) => {
  const user = findUser(req.body.email);
  // BAD: Token is just a timestamp
  const resetToken = Date.now().toString();
  user.resetToken = resetToken;
  sendEmail(user.email, `/reset?token=${resetToken}`);
});

// Attacker can predict tokens within a time window

Real-World Impact

Broken authentication can lead to:

  • Complete account takeover
  • Identity theft and financial fraud
  • Unauthorized access to sensitive data
  • Privilege escalation to admin accounts
  • Complete system compromise

Prevention Strategies

Implement Strong Password Policies

javascript
// Secure password validation
function validatePassword(password) {
  const minLength = 12;
  const hasUpperCase = /[A-Z]/.test(password);
  const hasLowerCase = /[a-z]/.test(password);
  const hasNumbers = /\d/.test(password);
  const hasSpecial = /[!@#$%^&*]/.test(password);
  
  // Check against common password list
  const isCommon = commonPasswords.includes(password.toLowerCase());
  
  return password.length >= minLength && 
         hasUpperCase && hasLowerCase && 
         hasNumbers && hasSpecial && 
         !isCommon;
}

Secure Session Management

javascript
// Secure session configuration
app.use(session({
  secret: process.env.SESSION_SECRET,
  name: '__Host-session', // Secure cookie prefix
  cookie: {
    httpOnly: true,      // Prevent XSS access
    secure: true,        // HTTPS only
    sameSite: 'strict',  // CSRF protection
    maxAge: 3600000      // 1 hour expiry
  },
  resave: false,
  saveUninitialized: false
}));

// Regenerate session ID after login
app.post('/login', (req, res) => {
  if (authenticate(req.body)) {
    req.session.regenerate(() => {
      req.session.userId = user.id;
      res.redirect('/dashboard');
    });
  }
});

Implement Rate Limiting

javascript
import rateLimit from 'express-rate-limit';

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // 5 attempts per window
  message: 'Too many login attempts, please try again later',
  standardHeaders: true,
  legacyHeaders: false,
});

app.post('/login', loginLimiter, handleLogin);

Use Multi-Factor Authentication

MFA significantly reduces the risk of account compromise. Even if credentials are stolen, attackers cannot access accounts without the second factor.

javascript
import speakeasy from 'speakeasy';

// Generate TOTP secret for user
const secret = speakeasy.generateSecret({
  name: 'MyApp (user@example.com)'
});

// Verify TOTP code
function verifyTOTP(userSecret, token) {
  return speakeasy.totp.verify({
    secret: userSecret,
    encoding: 'base32',
    token: token,
    window: 1 // Allow 1 step tolerance
  });
}

Security Checklist

  • Enforce strong password requirements (12+ characters, complexity)
  • Implement rate limiting on login endpoints
  • Regenerate session IDs after authentication
  • Use secure, HttpOnly, SameSite cookies
  • Never expose session IDs in URLs
  • Implement multi-factor authentication
  • Use cryptographically secure password reset tokens
  • Log and monitor failed authentication attempts
  • Hash passwords with bcrypt or Argon2

Practice Challenges

View all

Related Articles

View all