A04 · Cryptographic Failures
Program: Application Security — OWASP Top 10 and Threat Modeling Module: OWASP Top 10 — Web Application Security Risks Submodule: A04:2025 · Cryptographic Failures
Cryptographic Failures is any weakness in how data is protected at rest or in transit — from missing TLS, to storing passwords with MD5, to using AES-ECB, to reusing an IV. Renamed in 2021 from "Sensitive Data Exposure" because the symptom (exposed data) was distracting from the cause (broken crypto). Slightly demoted to A04 in 2025. Maps directly to STRIDE's Information Disclosure and Tampering.
1. What It Is
Anything that lets an attacker read, modify, or forge data that should have been protected by cryptography:
- Data transmitted or stored in cleartext when it shouldn't be.
- Encryption using deprecated or weak algorithms (DES, RC4, MD5, SHA-1, RSA-1024).
- Correct algorithms used in broken modes — AES-ECB, unauthenticated encryption (CBC without HMAC), reused nonces/IVs.
- Passwords stored with fast hashes (MD5, SHA-256) instead of memory-hard KDFs (Argon2id, scrypt, bcrypt).
- Keys hardcoded, checked into git, shipped in mobile apps, or stored beside the ciphertext.
- Randomness from
random.random()/Math.random()used to generate tokens, session IDs, or keys. - Certificate validation disabled in HTTP clients.
The consequence is not just "the data leaks" — it's often "the identity system is forgeable" (weak JWT signing, weak session tokens).
2. How It Happens — Common Patterns
| # | Pattern | Concrete example |
|---|---|---|
| 1 | Plain HTTP on any endpoint that touches data | POST /api/login over http://; middlebox captures the credential. |
| 2 | Password stored as sha256(password) | No salt, no work factor; cracked in seconds on GPU. |
| 3 | AES-ECB | Identical plaintext blocks produce identical ciphertext (see the "penguin image" example). |
| 4 | Reused IV/nonce (AES-GCM, ChaCha20-Poly1305) | Nonce reuse in GCM catastrophically breaks confidentiality and authentication. |
| 5 | Homegrown "encryption" | XOR with a constant, base64 as "encoding", custom cipher. |
| 6 | Weak JWT algorithm | Accepting alg: none or alg: HS256 when a public key is set (algorithm confusion). |
| 7 | Insecure random for security tokens | Session ID from Math.random(); predictable password reset tokens. |
| 8 | Certificates not validated | curl -k, verify=False in Python requests, self-signed accepted anywhere. |
| 9 | Keys in code / configs | AWS_SECRET_ACCESS_KEY=… committed to git; base64-embedded in a mobile binary. |
| 10 | Cleartext PII in logs, backups, error pages | GDPR + HIPAA breach in a single log line. |
| 11 | Downgrade to HTTP possible | No HSTS + http:// link somewhere → SSL-strip. |
| 12 | Missing at-rest encryption on the database / backups | Snapshot leaked = full dataset leaked. |
3. Prevention
Modern crypto has one rule: don't invent, don't tune knobs, use a vetted high-level primitive. Use one of:
libsodium/NaCl(crypto_secretbox,crypto_box)- Tink (Google) — high-level, hard to misuse
- Age /
age-encryption.orgfor file/blob encryption - Language stdlib high-level APIs (
cryptography.fernetin Python,cryptographymodule hazmat only for library authors)
Concrete guidance:
- In transit — TLS 1.2+ (prefer 1.3), disable TLS 1.0/1.1, strong cipher suites only, HSTS with
includeSubDomains; preload, OCSP stapling. - At rest — full-disk encryption is table stakes; column-level encryption for sensitive fields; authenticated encryption (AES-GCM/AES-GCM-SIV/ChaCha20-Poly1305) — never AES-ECB, never AES-CBC without a MAC.
- Passwords — Argon2id (recommended by OWASP/IETF), bcrypt (fallback for legacy platforms), scrypt. Tune to ~250ms on your hardware. Never MD5/SHA-*.
- Tokens / IDs / nonces —
secrets.token_urlsafe(32)in Python,crypto.randomBytesin Node,SecureRandomin Java. NeverMath.random(). - Keys — generated by a KMS (AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault); rotate on a schedule and on personnel change; never in source control, never in environment variables outside a secrets manager.
- Certificate validation on in every HTTP client. If you need to trust a private CA, add it to the trust store — don't disable validation.
- JWT — pin the algorithm to a specific value on the verifier side; never trust
algfrom the token. Prefer signed cookies with a rotating server-side secret for browser sessions.
4. Detection & Testing
- TLS scanners —
testssl.sh, SSL Labs, Mozilla Observatory. Ideal in CI against staging. - Secret scanners —
gitleaks,trufflehog, GitHub secret scanning; extend with custom regex for internal secret formats. Rotate any leaked secret; deleting the commit is not enough. - SAST rules — most tools ship rules for
Math.random,MD5,SHA-1,verify=False,alg: none. - DAST + config audit — checks HSTS, cookie flags (
Secure,HttpOnly,SameSite), TLS version. - Manual review for password hashing, JWT verification, custom encryption code. These are high-risk areas that scanners routinely miss.
- Post-quantum readiness assessment — inventory of asymmetric primitives (RSA, ECDSA, DH, ECDH) that will need to migrate to ML-KEM / ML-DSA by NIST's post-quantum timeline (2030–2035).
5. Key Takeaways
- The category was renamed from "Sensitive Data Exposure" because the exposure is the symptom; broken crypto is the cause.
- Two rules cover 90% of cases: encrypt in transit with TLS; hash passwords with Argon2id/bcrypt/scrypt.
- Do not write crypto code. Use libsodium / Tink / language stdlib high-level primitives. If your code contains a nonce, an IV, or a block-mode selection, it should have been reviewed by someone who knows crypto.
- Keys are secrets — they belong in a KMS, not in code, config, or environment variables outside a secrets manager.
- Post-quantum migration is coming — start the inventory now.
6. Glossary (this submodule)
- Authenticated Encryption (AEAD) — encryption that also protects integrity/authenticity in one primitive (AES-GCM, ChaCha20-Poly1305); the modern default.
- KDF (Key Derivation Function) — function that turns a password or master secret into a key (Argon2id, scrypt, bcrypt, PBKDF2, HKDF).
- KMS — Key Management Service; managed system that generates, stores, rotates and audits cryptographic keys.
- CSPRNG — Cryptographically Secure Pseudo-Random Number Generator; produces unpredictable output suitable for keys and tokens.
- HSTS — HTTP Strict Transport Security; header telling the browser to only ever use HTTPS for this origin.
- Nonce / IV — value used once per encryption to make identical plaintexts encrypt to different ciphertexts. Reuse is catastrophic in most modes.
- PQC (Post-Quantum Cryptography) — cryptographic primitives believed to resist quantum computers; NIST standardized ML-KEM (Kyber) and ML-DSA (Dilithium) in 2024.
7. What's Next
- A05 · Injection — the classic "attacker-controlled input reaches a sensitive interpreter" pattern.
- Cross-refs: A02 · Security Misconfiguration (TLS/HSTS live at the configuration layer), A07 · Authentication Failures (password storage and session tokens are the two crypto surfaces that decide who you are).