Crypto Failures
OWASP Top 10
Course 1 · Chapter 2 · A02: Cryptographic Failures
Number two on the list is about protecting sensitive data — and what goes wrong when the cryptography that's supposed to protect it is weak, misused, or simply absent. This is a category where your existing courses do much of the heavy lifting: it's largely "the HTTPS course (data in transit) plus the password-storage chapter of the Auth course (data at rest & hashing), generalized." This chapter maps the whole category and points you to that depth.
A02: Cryptographic Failures — and a Telling Rename
In 2021 this category was renamed from "Sensitive Data Exposure" to "Cryptographic Failures." That rename matters: the old name described the symptom (data got exposed), the new one names the root cause (the cryptography failed or was missing). It's a reminder that exposed data is almost always a downstream result of a crypto mistake — so you fix it by getting the cryptography right, not by chasing leaks. It ranks #2.
Step One: Know What's Sensitive
You can't protect data correctly until you know which data needs protecting and what kind. Before any crypto, classify your data and its requirements:
- What is sensitive? — passwords, payment/card data, health records, personal data (PII), session tokens, API keys, anything with legal/regulatory weight (GDPR, PCI-DSS, HIPAA).
- In transit, at rest, or both? — data moving over the network needs transport protection; data stored needs at-rest protection; most sensitive data needs both.
- Does it need to be recoverable? — this decides hashing vs encryption (below) — the single most common crypto-choice mistake.
The Common Cryptographic Failures
| Failure | Example | Deep-dive |
|---|---|---|
| Cleartext transmission | plain HTTP, unencrypted email/DB connections | HTTPS course |
| Weak / outdated algorithms | MD5, SHA-1, DES, RC4, AES-ECB mode | HTTPS Ch. 8 |
| Weak password hashing | fast hashes (MD5/SHA-256) instead of Argon2/bcrypt | Auth Ch. 2 |
| Encrypting what should be hashed | storing reversible passwords "encrypted" | Auth Ch. 2 |
| Poor key management | hardcoded/default keys, keys in source control | this chapter |
| No encryption at rest | plaintext PII / card data in the database | this chapter |
| Weak randomness | Math.random() for tokens/keys (not a CSPRNG) | Auth Ch. 4 |
| Improper cert validation | disabling TLS verification "to make it work" | HTTPS Ch. 5/11 |
The Most Common Mistake: Hashing vs Encryption
The crypto-choice error that appears again and again: using the wrong primitive for the data. The rule from the Auth course generalizes here:
The Defences
- Classify data first — know what's sensitive and its in-transit/at-rest/regulatory needs; don't store sensitive data you don't need.
- Encrypt in transit — TLS everywhere (HTTPS + HSTS), including internal and DB connections — the entire HTTPS course.
- Encrypt at rest — sensitive fields/databases encrypted with strong, modern algorithms (AES-GCM and similar AEAD modes).
- Hash passwords correctly — slow, salted Argon2id / bcrypt; never fast hashes, never "encryption" (Auth Ch. 2).
- Manage keys properly — never hardcode keys or commit them to source control; use a secrets manager / KMS; rotate keys; separate keys from the data they protect.
- Use a CSPRNG for tokens/keys/IVs —
crypto.randomBytes, neverMath.random(). - Validate TLS properly — never disable certificate verification; pin algorithm versions (no SSL/TLS 1.0/1.1, no weak ciphers).
- Don't cache sensitive data — appropriate cache-control headers so secrets aren't stored by browsers/proxies.
libsodium/the language's standard crypto, a maintained password-hashing library, a KMS), configured per current guidance. Reserve "implementing crypto" for specialists; for everyone else, the win is choosing the right well-built tool and using it correctly — exactly the lesson from HTTPS and Auth.
Hands-On Exercises
For each, state the protection needed (encrypt in transit / encrypt at rest / hash) and why: (a) a user's login password; (b) a credit-card number you must charge monthly; (c) data sent from the browser to your API; (d) session tokens stored in the database. Note any that need more than one.
📄 View solutionSpot every cryptographic failure in this design and fix each: passwords stored as MD5; the site served over HTTP; the encryption key hardcoded in the source and committed to git; session IDs generated with Math.random(). Map each to its A02 sub-category.
Explain the hashing-vs-encryption decision: which to use for passwords vs for a recoverable card number, and why storing passwords "encrypted" is a failure. Then explain why "don't roll your own crypto" is the strongest single piece of A02 advice, with two ways homemade crypto goes wrong.
📄 View solutionChapter 2 Quick Reference
- A02 Cryptographic Failures (#2) — sensitive data unprotected because crypto is weak, misused, or absent; renamed from "Sensitive Data Exposure" to name the cause, not the symptom
- Classify first — know what's sensitive (passwords, PII, cards, tokens) and whether it needs protection in transit, at rest, or both
- Common failures: cleartext (HTTP) · weak algorithms (MD5/SHA-1/DES/ECB) · weak password hashing · encrypting-what-should-be-hashed · poor key management · no at-rest encryption · weak randomness · bad cert validation
- Hash vs encrypt: hash what you only verify (passwords → Argon2id/bcrypt, salted/slow); encrypt what you must read back (cards) — storing passwords "encrypted" is a failure
- Defences: classify · TLS in transit (HTTPS+HSTS) · AES-GCM at rest · proper key management (no hardcoded keys/secrets in git, use a KMS) · CSPRNG · valid TLS · no caching secrets
- Don't roll your own crypto — use vetted libraries/high-level constructs; homemade crypto fails subtly and invisibly
- Deep-dives: HTTPS (in transit), Auth Ch. 2 (password hashing / at rest)
- Next chapter: A03 Injection — SQLi, XSS & the data-vs-code family (→ SQLi & XSS courses)