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.
# 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.
<!-- 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:
// 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:
// 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 windowReal-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
// 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
// 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
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.
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 allTrust Issues
Premium content behind a paywall. But is the paywall actually protecting anything?
Open Doors
An admin panel with a login page. But does the API care about your login?
Password Reset Fail
A password reset flow. But is the token really unpredictable?
Remember Me
A 'remember me' checkbox. What's it actually remembering?
JWT None Algorithm
JWT tokens. But AI forgot about the 'none' algorithm.