Cryptographic & Authentication Failures
A02: Cryptographic Failures
Cryptographic failures occur when sensitive data is not properly protected through encryption, hashing, or secure protocols. This was previously known as "Sensitive Data Exposure" — the OWASP rename reflects that the root cause is usually a failure in cryptographic implementation, not just the exposure itself.
What Needs Protection
Data that requires cryptographic protection:
- Passwords (hashing, never encryption)
- Payment card numbers (PCI DSS requirement)
- Personal identifiable information (GDPR, CCPA)
- Health records (HIPAA)
- Authentication tokens and session keys
- API keys and secrets
- Data in transit between services
- Database backups
Data that probably does not:
- Public content (blog posts, marketing pages)
- Publicly available statistics
- Open-source code
Plaintext Passwords
Storing passwords in plaintext is the most fundamental cryptographic failure. If the database is compromised, every user's password is immediately exposed.
Real example: 2013 Adobe breach
- 153 million user records stolen
- Passwords encrypted (not hashed) with 3DES in ECB mode
- Same password produced the same ciphertext
- Password hints stored in plaintext alongside encrypted passwords
- Researchers used the hints to crack passwords in bulk
- "hint: same as banking password" appeared thousands of times
The fix: Hash passwords with bcrypt or Argon2id. Never encrypt them.
Encrypted passwords can be decrypted. Hashes cannot be reversed.
Weak Hashing
Not all hashing algorithms are suitable for passwords.
Unsuitable for passwords:
- MD5: Fast to compute. Crackable at billions of hashes/second.
Hashcat on a modern GPU cracks MD5 at ~60 billion/sec.
- SHA1: Also fast. Collision attacks proven (SHAttered, 2017).
- SHA256: Cryptographically strong, but too fast for passwords.
Speed is a liability — attackers can brute-force quickly.
Suitable for passwords:
- bcrypt: Deliberately slow. Configurable work factor.
Built-in salt. Industry standard for 25+ years.
- Argon2id: Winner of the Password Hashing Competition (2015).
Memory-hard — resistant to GPU and ASIC attacks.
Recommended for new projects.
- scrypt: Memory-hard. Good alternative to Argon2id.
The key property: these algorithms are intentionally slow.
A function that takes 100ms to verify one password makes
brute-forcing billions of passwords computationally infeasible.
Real example: 2012 LinkedIn breach
- 6.5 million password hashes leaked (later confirmed 117 million)
- SHA1 without salt
- Within hours, millions were cracked
- Identical passwords had identical hashes (no salt)
- Attackers used precomputed rainbow tables
If LinkedIn had used bcrypt, the same hardware would take
centuries instead of hours to crack the same password set.
Encryption at Rest
Data stored on disk should be encrypted when it contains sensitive information.
What "at rest" means:
- Database files on disk
- Backup files
- Log files containing sensitive data
- Files in cloud storage (S3, GCS, Azure Blob)
- Data on laptop hard drives
Real example: 2006 US Veterans Affairs breach
- Laptop stolen from employee's home
- 26.5 million veterans' SSNs and birth dates
- Data was not encrypted on the hard drive
- Full disk encryption would have made the data inaccessible
Cloud storage defaults:
- AWS S3: Server-side encryption available, now default for new buckets
- GCP Cloud Storage: Encrypted by default
- Azure Blob: Encrypted by default
- But: encryption with provider-managed keys protects against
physical theft, not against anyone with API access to your account
Encryption in Transit
Data moving between systems should be encrypted with TLS.
Requirements:
- Use TLS 1.2 or 1.3 (never SSL, TLS 1.0, or TLS 1.1)
- Use strong cipher suites (AES-GCM, ChaCha20-Poly1305)
- Enable HSTS (HTTP Strict Transport Security) to prevent downgrade
- Redirect all HTTP to HTTPS
- Use TLS between internal services, not just at the edge
Common failures:
- Mixed content: HTTPS page loads scripts over HTTP
- Certificate validation disabled in code (verify=False)
- Self-signed certificates in production without pinning
- Internal services communicating over plaintext HTTP
- Database connections without TLS
Real example: 2014 Heartbleed (CVE-2014-0160)
- Bug in OpenSSL allowed reading server memory
- Could extract private keys, session tokens, passwords
- Affected ~17% of all HTTPS servers
- The fix was simple (patch OpenSSL), but the vulnerability
had existed for two years before discovery
Cryptographic Anti-Patterns
Never do these:
- Roll your own cryptography (use established libraries)
- Use ECB mode for block ciphers (patterns leak through)
- Use the same key for encryption and authentication
- Hardcode encryption keys in source code
- Use deprecated algorithms (DES, 3DES, RC4, MD5 for integrity)
- Disable certificate validation to "fix" TLS errors
- Store encryption keys next to encrypted data
- Use encryption when you need hashing (passwords)
- Use hashing when you need encryption (data you need back)
A07: Identification & Authentication Failures
Authentication failures allow attackers to compromise passwords, keys, or session tokens, or exploit implementation flaws to assume other users' identities.
Weak Passwords
Most common passwords found in breaches (still, in 2025):
123456, password, 12345678, qwerty, abc123, monkey, letmein
The problem is not that users choose weak passwords.
The problem is that applications allow them.
Prevention:
- Enforce minimum length (12+ characters recommended)
- Check against breached password lists (Have I Been Pwned API)
- Do not enforce complexity rules (they backfire)
- Allow and encourage passphrases
- Support password managers (allow paste, long passwords)
Credential Stuffing
Attackers use username/password pairs from one breach to log into other services. Because users reuse passwords across sites, this works at alarming rates.
How credential stuffing works:
1. Attacker obtains breach database (millions of email/password pairs)
2. Attacker uses automated tools to try each pair against your login
3. Success rate: typically 0.1% to 2%
4. On a database of 10 million credentials, that is 10,000-200,000
compromised accounts
Real example: 2020 Nintendo credential stuffing
- 300,000 Nintendo accounts compromised
- Attackers used credentials from other breaches
- Purchased games and digital content with stored payment methods
- Nintendo forced password resets and encouraged MFA
Prevention:
- Rate limit login attempts (by IP and by account)
- Detect and block automated login attempts
- Require MFA for sensitive accounts
- Monitor for login anomalies (unusual location, device)
- Notify users of suspicious login attempts
- Check new passwords against breached password databases
Missing Multi-Factor Authentication
Passwords alone are insufficient for accounts with:
- Administrative access
- Access to customer data
- Financial transaction capability
- Access to source code or infrastructure
Real example: 2021 Colonial Pipeline breach
- Attackers accessed the VPN with a single compromised password
- The VPN account did not have MFA enabled
- Led to a ransomware attack that shut down fuel supply
for the US East Coast for six days
- $4.4 million ransom paid (most later recovered)
- A single MFA requirement would have prevented the breach
Broken Authentication Patterns
Session token in URL:
https://app.com/dashboard?session=abc123def456
- Leaked in browser history, referrer headers, logs, shared links
- Session tokens belong in cookies with HttpOnly and Secure flags
Credential transmission without TLS:
- Passwords sent over HTTP can be intercepted by anyone on the network
- This includes login forms, API authentication, and password resets
No account lockout or rate limiting:
- Allows unlimited password guessing
- A 6-character lowercase password can be brute-forced in seconds
- Progressive delays (1s, 2s, 4s, 8s...) are better than hard lockout
(hard lockout enables denial-of-service against specific accounts)
Password reset flaws:
- Predictable reset tokens
- Reset tokens that don't expire
- Security questions with guessable answers (mother's maiden name)
- Sending new password in plaintext via email
Authentication Best Practices
1. Use bcrypt or Argon2id for password hashing
2. Enforce minimum password length (12+), not complexity
3. Check passwords against known breach databases
4. Implement MFA for admin and sensitive accounts
5. Rate limit login attempts by IP and account
6. Use progressive delays, not hard lockout
7. Session tokens: random, HttpOnly, Secure, SameSite
8. Password reset: token-based, time-limited (15-60 minutes)
9. Log all authentication events
10. Notify users of login from new devices/locations
How These Vulnerabilities Combine
Breach chain example:
1. Application stores passwords with MD5 (A02: Cryptographic Failure)
2. Database backup in public S3 bucket (A02: Cryptographic Failure)
3. Attacker downloads backup, cracks MD5 hashes in minutes
4. Attacker uses credentials on the production application
5. No MFA required (A07: Authentication Failure)
6. Attacker now has legitimate access to user accounts
Every step in this chain is independently preventable.
Real Breach Timeline
2011 — Sony PlayStation Network
- 77 million accounts compromised
- Passwords hashed with a single unsalted hash
- Credit card data stored with weak encryption
- No intrusion detection — Sony discovered the breach
only when the data appeared for sale online
2012 — LinkedIn
- 117 million SHA1 password hashes leaked
- No salt, enabling rapid cracking with rainbow tables
- LinkedIn migrated to bcrypt after the breach
2013 — Adobe
- 153 million records
- 3DES encryption (not hashing) in ECB mode
- Plaintext password hints stored alongside
- Same password always produced same ciphertext
2019 — Facebook
- Hundreds of millions of passwords stored in plaintext
- Accessible to thousands of employees via internal logs
- Discovered during routine security review
- No evidence of external access, but the exposure existed for years
Each of these breaches would have been prevented or dramatically
reduced by using bcrypt, encrypting data at rest, and implementing
proper access controls on stored credentials.
Common Pitfalls
-
Using SHA256 for passwords: SHA256 is a strong hash for data integrity, but it is too fast for password hashing. Attackers can compute billions of SHA256 hashes per second. Use bcrypt or Argon2id, which are deliberately slow.
-
Encrypting instead of hashing passwords: Encrypted passwords can be decrypted if the key is compromised. Hashed passwords cannot be reversed. Passwords should always be hashed, never encrypted.
-
Storing encryption keys with the data: Encrypting data and storing the key in the same database, config file, or repository defeats the purpose. Keys should be managed separately (KMS, HSM, vault).
-
Assuming HTTPS means end-to-end encryption: TLS encrypts data in transit between client and server. The server sees plaintext. If you need the server to not see the data, you need client-side encryption (end-to-end).
-
Hard account lockout: Locking an account after N failed attempts enables denial-of-service. An attacker can lock any account by intentionally failing login. Use progressive delays instead.
-
Security questions as authentication: "What is your mother's maiden name?" is not a secret. It is public information on social media. Security questions are a weak form of authentication that should not be the sole recovery mechanism.
Key Takeaways
- Hash passwords with bcrypt or Argon2id. Never MD5, SHA1, SHA256, plaintext, or encryption. Speed is the enemy for password hashing.
- Encrypt sensitive data at rest and in transit. Use TLS 1.2+ everywhere, including between internal services.
- The Adobe breach shows why ECB mode, password hints, and encryption-instead-of-hashing are catastrophic failures.
- Credential stuffing works because users reuse passwords. Rate limiting, breach database checks, and MFA are essential defenses.
- Missing MFA on critical systems has caused some of the most damaging breaches (Colonial Pipeline, Uber). Require it for admin access and sensitive operations.
- Cryptographic failures and authentication failures compound each other. Weak hashing plus no MFA plus exposed backups equals total compromise.