Cryptographic Failures: Protecting Data at Rest and in Transit
Cryptographic Failures (formerly called "Sensitive Data Exposure") covers situations where data that should be encrypted is either not encrypted at all, or is encrypted using weak, broken algorithms. The name change in 2021 was deliberate — the root cause is almost always a cryptographic failure, not just accidental exposure.
Common failure patterns:
# Storing passwords in plaintext or with weak hashing
# WRONG: MD5 is cryptographically broken for passwords
password_hash = md5(user_password)
# WRONG: SHA-256 without a salt is vulnerable to rainbow table attacks
password_hash = sha256(user_password)
# CORRECT: Use a purpose-built password hashing algorithm
import bcrypt
password_hash = bcrypt.hashpw(user_password.encode(), bcrypt.gensalt(rounds=12))
The distinction matters enormously: MD5 and SHA-256 are designed to be fast (for checksums and integrity verification). Password hashing algorithms like bcrypt, scrypt, and Argon2 are designed to be slow and memory-intensive, making brute-force attacks computationally expensive even if the hash database is stolen.
Transmitting sensitive data over HTTP (not HTTPS): Any data sent over unencrypted HTTP can be intercepted by anyone on the network path — ISPs, coffee shop Wi-Fi operators, or anyone running a packet capture. All web applications must enforce HTTPS with a valid TLS certificate and redirect HTTP to HTTPS.
# Correct HTTP response headers for transport security
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Security Misconfiguration: The "Default Settings" Trap
Security Misconfiguration is the broadest category in the Top 10. It covers any situation where a system is deployed with insecure default settings, unnecessary features enabled, or missing hardening. It's the most common finding in penetration tests because it requires no sophisticated attack — just checking whether defaults were changed.
High-impact examples:
# Default credentials left unchanged
# MongoDB with no authentication (was the default before v3.0)
mongo --host production-db.internal # No password required
# Verbose error messages exposing stack traces in production
# Django DEBUG=True in production exposes source code, environment variables, and SQL queries
# Cloud storage buckets left publicly readable
aws s3api get-bucket-acl --bucket company-backups
# Returns: "AllUsers: READ" — anyone on the internet can download your backups
# Unnecessary HTTP methods enabled
# TRACE method enabled on a web server enables Cross-Site Tracing (XST) attacks
curl -X TRACE https://api.example.com/
The fix is systematic hardening:
1. Maintain a hardening checklist for every component (web server, database, cloud service, container image).
2. Disable all features, ports, and services not explicitly required.
3. Change all default credentials before deployment.
4. Use infrastructure-as-code to enforce configuration — if the config is in code, it can be reviewed, tested, and audited.
5. Run automated configuration scanners (like trivy, kube-bench, or AWS Security Hub) as part of CI/CD.
Key Point: Security Misconfiguration is the category most amenable to automation. Tools like Trivy (container image scanning), tfsec (Terraform security scanning), kube-bench (Kubernetes CIS benchmark), and cloud provider security posture management services can detect misconfigurations before they reach production. The engineering investment in these tools pays dividends far beyond manual review.