Why the OWASP Top 10 alone isn't enough
OWASP Top 10 lists the most critical web application security risk categories. It deliberately avoids specific vulnerabilities — it's a framework for thinking about risk, not a checklist for testing. That distinction matters in practice.
A broken access control finding on a public, read-only resource is a very different problem from broken access control on a financial transaction endpoint. Both land in A01. Neither the OWASP list nor a standard vulnerability scanner tells you which one your app has — or whether either is actually exploitable end to end.
What follows is a category-by-category breakdown of what each Top 10 entry actually looks like in a running web application, what proof of exploitation requires, and how to test for it.
Broken Access Control
The most commonly confirmed vulnerability category across automated simulations. Broken access control means the application makes an authorization decision — but makes it incorrectly, incompletely, or not at all.
The most exploitable patterns are:
- IDOR — accessing another user's resource by changing a numeric ID
- Privilege escalation — calling admin endpoints as a regular user
- Missing function-level auth — endpoints that skip auth checks when called directly
- CORS misconfiguration — cross-origin requests accepted from arbitrary origins
# IDOR: attacker reads another user's invoice
GET /api/invoices/4821 HTTP/1.1
Authorization: Bearer <attacker_token> ← owns invoice 4820, not 4821
HTTP/1.1 200 OK ← should be 403
{ "id": 4821, "amount": 12400, "client": "Acme Corp" }Proof of exploitation requires a confirmed 200 response with data belonging to a different account — not just the absence of a 403.
Cryptographic Failures
Formerly "Sensitive Data Exposure," this category covers cases where data is transmitted or stored without adequate cryptographic protection. The exploitable variants in web apps are more specific than the name suggests.
What actually gets confirmed in testing:
- Sensitive data returned in API responses that should be server-side only
- Weak JWT secrets brute-forceable offline with a wordlist
- Tokens or session identifiers exposed in URL parameters (visible in server logs)
- TLS not enforced — HTTP fallback accepted without redirect
# Token exposed in URL — logged by CDN, proxy, and browser history GET /api/download?token=eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1OH0.abc123 Host: app.example.com # JWT with weak secret — crackable in seconds $ hashcat -a 0 -m 16500 jwt.txt rockyou.txt eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo1OH0.abc123:password123
Injection
SQL injection, command injection, LDAP injection, SSTI — any case where untrusted data is sent to an interpreter. SQL injection specifically has declined in prevalence due to ORMs, but it remains high impact wherever it exists.
Server-Side Template Injection (SSTI) has increased as teams build internal dashboards and email templating on frameworks like Jinja2, Twig, and Handlebars. It's frequently missed by static analysis tools.
# SSTI probe — payload evaluates to 49 if template engine is active
POST /api/email/preview HTTP/1.1
Content-Type: application/json
{ "template": "Hello {{7*7}}" }
HTTP/1.1 200 OK
{ "preview": "Hello 49" } ← confirmed template injectionA response of "Hello 49" confirms the server evaluated the expression. From here, payload escalation can achieve remote code execution on Jinja2, Twig, and others.
Insecure Design
The hardest OWASP category to test with a scanner. Insecure design refers to missing security controls at the architecture level — rate limiting on authentication endpoints, lack of MFA for high-value actions, password reset flows that don't validate token ownership.
Testable patterns include:
- Login endpoint with no rate limiting — allows credential stuffing at full speed
- Password reset token that doesn't expire and isn't invalidated on use
- Absence of re-authentication before high-value actions (payment, email change)
# 100 login attempts, no rate limit response
for i in $(seq 1 100); do
curl -s -o /dev/null -w "%{http_code}" -X POST /api/auth/login -d '{"email":"target@example.com","password":"attempt'$i'"}'
done
# Output: 401 401 401 401 401 ... (never 429 Too Many Requests)Security Misconfiguration
The broadest category. Misconfiguration covers server banners leaking version info, default credentials, open cloud storage buckets, verbose error messages, unnecessary HTTP methods enabled, and missing security headers.
Security headers are the most common finding — and frequently the least impactful in isolation. Missing Content-Security-Policy doesn't confirm exploitability; it raises the risk that a future XSS finding will be more severe.
HTTP/1.1 200 OK Server: Apache/2.4.51 (Ubuntu) ← version disclosure X-Powered-By: PHP/8.0.3 ← stack disclosure # Missing: Strict-Transport-Security # Missing: Content-Security-Policy # Missing: X-Frame-Options
When testing, separate hardening signals (missing headers, banner disclosure) from confirmed attack paths. They are different risk categories and should be scored differently.
Vulnerable and Outdated Components
Libraries, frameworks, and runtimes with known CVEs. The challenge for web app testing is that a CVE existing doesn't mean the vulnerable code path is reachable in your application.
The exploitable subset is: components with unauthenticated, remotely-triggerable CVEs where the specific endpoint or functionality is exposed in your app. Log4Shell (CVE-2021-44228) was a dramatic example — it was reachable through HTTP headers in almost every Java application.
Dynamic testing catches this better than SCA tools when the vulnerability is in a request-handling code path — a scanner can attempt the payload and observe the response.
Identification and Authentication Failures
Session management weaknesses, broken authentication flows, and account takeover paths. This category covers a wide range of issues — from JWT vulnerabilities to insecure session cookie flags.
The highest-impact patterns to test:
- Session cookies missing
HttpOnlyandSecureflags - Session not invalidated on logout (token replay succeeds post-logout)
- JWT with
alg: noneaccepted — signature verification bypassed entirely - Password reset links that don't expire or can be reused
# alg:none JWT bypass — forged token, no signature required
Header: { "alg": "none", "typ": "JWT" }
Payload: { "user_id": 1, "role": "admin" }
Signature: (empty)
GET /api/admin/users HTTP/1.1
Authorization: Bearer eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyX2lkIjoxLCJyb2xlIjoiYWRtaW4ifQ.
HTTP/1.1 200 OK ← admin access granted with forged tokenSoftware and Data Integrity Failures
Covers insecure deserialization and CI/CD pipeline integrity issues. In web application context, the most commonly testable pattern is insecure deserialization — where an application deserializes untrusted data from a user-controlled input.
PHP object injection, Java deserialization via serialized object payloads, and Python pickle deserialization are the primary attack surfaces. Less common than other categories but critical when present — exploitable deserialization typically achieves remote code execution.
Security Logging and Monitoring Failures
Not a finding in the traditional sense — this category describes what happens after an attacker is already in. Without adequate logging, breaches aren't detected, and forensic investigation is impossible.
From a testing perspective, you can verify the negative: attempt a series of failed logins, IDOR probes, and admin endpoint calls, then check whether any alerting or log enrichment fired. If not, the application has a detection gap that extends the attacker's window significantly.
Server-Side Request Forgery (SSRF)
SSRF occurs when an application fetches a remote resource from a user-supplied URL without adequate validation. The attacker forces the server to make requests to internal services, cloud metadata endpoints, or arbitrary external destinations.
In cloud environments (AWS, GCP, Azure), the immediate target is the instance metadata service, which can return IAM credentials.
# SSRF targeting AWS metadata endpoint
POST /api/fetch-preview HTTP/1.1
Content-Type: application/json
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }
HTTP/1.1 200 OK
{ "preview": "my-ec2-role" } ← internal metadata reachable
# Follow-up to retrieve credentials
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/my-ec2-role" }
# Returns: AccessKeyId, SecretAccessKey, TokenBlind SSRF — where the server makes the request but doesn't return the response body — requires out-of-band detection via a callback URL. The application fetches your URL; you observe the DNS or HTTP request arriving at your listener.
Testing priority: which categories are most likely exploitable
Based on confirmed findings across web application simulations, the categories that most frequently produce exploitable vulnerabilities in production apps are:
A01 Broken Access Control
IDOR and privilege escalation confirmed most frequently — almost every multi-user app has at least one instance
A07 Authentication Failures
Session and JWT weaknesses common in apps that rolled their own auth or migrated between auth systems
A03 Injection
SQL injection rare with modern ORMs, but SSTI and command injection still appear regularly in template and search features
A10 SSRF
High impact when present in cloud environments — increasingly common as apps integrate webhook and URL-preview features
A05 Misconfiguration
Extremely common but mostly low-impact in isolation; dangerous when combined with other findings
The difference between presence and exploitability
A vulnerability scanner can confirm a missing header in under a second. Confirming that a broken access control finding leads to unauthorized data access requires a multi-step proof: authenticate as user A, request a resource owned by user B, confirm the response contains user B's data.
For each OWASP category, the exploitability question isn't "does this pattern exist?" — it's "can an attacker reach a meaningful impact from this entry point?" That requires simulation, not just detection.
CVSS 3.1 provides a scoring framework for this: Attack Vector, Attack Complexity, Privileges Required, User Interaction, Scope, and Impact are all components of whether a finding is practically exploitable — not just theoretically present.
Test your app against OWASP Top 10
Nautillo Pro runs goal-driven simulations that attempt real exploit paths across all OWASP Top 10 categories — with CVSS 3.1 scoring and HTTP proof-of-concept for every confirmed finding. No manual setup required.