๐ What Is It?
Broken Authentication occurs when API authentication mechanisms are poorly implemented, allowing attackers to compromise authentication tokens, passwords, session IDs, or exploit implementation flaws to assume other users' identities temporarily or permanently.
API02
OWASP Rank
62%
APIs Tested
Minutes
Time to Exploit
โ ๏ธ Common Exploits
- Brute Force: No rate limiting allows password guessing
- Credential Stuffing: Using leaked credentials from other breaches
- Weak JWT: Predictable secrets, no expiration, algorithm confusion
- Token Theft: Stealing and reusing authentication tokens
- Missing MFA: Single-factor authentication on sensitive operations
- Weak Passwords: No complexity requirements or length enforcement
๐ด Attack Flow
1. Attacker identifies login endpoint
โ
2. No rate limiting detected
โ
3. Launches automated brute force attack
โ
4. Tries 10,000 common passwords
โ
5. BREACH: Account compromised!
โ
2. No rate limiting detected
โ
3. Launches automated brute force attack
โ
4. Tries 10,000 common passwords
โ
5. BREACH: Account compromised!
โ Vulnerable Code
// Bad: Weak JWT implementation
const token = jwt.sign(
{ userId: user.id },
'secret123', // Weak secret!
{ algorithm: 'HS256' } // No expiration!
);
// Bad: No rate limiting on login
@app.route('/api/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
user = User.query.filter_by(username=username).first()
if user and user.check_password(password):
return jsonify({'token': generate_token(user)})
return jsonify({'error': 'Invalid credentials'}), 401
// Bad: Weak password policy
if len(password) >= 5: # Too short!
create_user(username, password)
โ Secure Code
// Good: Secure JWT with expiration
const token = jwt.sign(
{
userId: user.id,
exp: Math.floor(Date.now() / 1000) + (15 * 60) // 15 min
},
process.env.JWT_SECRET, // Strong secret from env
{ algorithm: 'RS256' } // Asymmetric signing
);
// Good: Rate limiting + account lockout
@limiter.limit("5 per minute")
@app.route('/api/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
user = User.query.filter_by(username=username).first()
# Check if account is locked
if user and user.is_locked():
return jsonify({'error': 'Account locked'}), 403
if user and user.check_password(password):
user.reset_failed_attempts()
return jsonify({'token': generate_token(user)})
# Increment failed attempts
if user:
user.increment_failed_attempts()
return jsonify({'error': 'Invalid credentials'}), 401
// Good: Strong password policy
def validate_password(password):
if len(password) < 12:
raise ValueError("Password too short")
if not has_uppercase(password):
raise ValueError("Needs uppercase")
if is_common_password(password):
raise ValueError("Password too common")
โ Prevention Checklist
- Implement rate limiting on all auth endpoints
- Use strong, random secrets for token generation
- Set short expiration times (15 min access tokens)
- Implement refresh token mechanism
- Use asymmetric algorithms (RS256) for JWTs
- Enforce strong password policies (12+ chars)
- Implement MFA for sensitive operations
- Hash passwords with bcrypt/argon2
- Implement account lockout after failed attempts
- Validate token signatures and expiration
- Implement token revocation on logout
- Never expose tokens in URLs or logs
๐ Detection & Tools
Testing Tools:
Burp Suite
OWASP ZAP
Postman
Hydra
Medusa
jwt_tool
JohnTheRipper
Security Libraries:
Passport.js
Spring Security
Auth0
OAuth 2.0
OpenID Connect
Flask-Limiter
How to Test:
- Test for rate limiting (try 100+ login attempts)
- Check JWT algorithm and secret strength
- Verify token expiration is enforced
- Test with weak passwords (123456, password)
- Try credential stuffing with known breaches
- Test token reuse after logout
๐ Real-World Breaches
- T-Mobile (2021): SIM swapping via weak API authentication, no MFA enforcement
- Twitter (2020): OAuth token leak exposed 5.4M accounts
- Experian (2021): Weak password reset tokens allowed credit report access
- Robinhood (2021): Social engineering due to insufficient authentication controls
- Capital One (2019): Stolen credentials led to 100M+ records breach
๐ Quick Tips
- DO NOT use weak secrets like 'secret' or 'password'
- DO NOT create tokens without expiration
- DO NOT skip rate limiting on auth endpoints
- DO use RS256 or ES256 for JWTs
- DO implement account lockout after 5 failures
- DO require MFA for sensitive operations
- DO log all authentication events
๐ Compliance
Related Standards:
- PCI-DSS Requirement 8.1-8.8
- GDPR Art. 32 - Security of Processing
- NIST 800-63B - Digital Identity
- SOC 2 CC6.1 - Logical Access
- ISO 27001 A.9.2, A.9.4
- HIPAA ยง164.312(a)(1)