OWASP Top 10 Overview
OWASP publishes the canonical risk-ranked list of web vulnerability classes. The list is not a checklist of bugs — it is a prioritization model used by every SAST/DAST vendor, every compliance regime (PCI DSS 6.5, ISO 27034), and every bug-bounty scope. Knowing why A01 is Broken Access Control (and not Injection, which it was in 2017) tells you how the threat landscape has moved in five years.
The Core Concept
Section titled “The Core Concept”The Top 10 is built from incident data contributed by dozens of organizations (AppSec teams, SaaS providers, bug-bounty platforms). OWASP 2021 swapped the order based on incidence rate, exploitability, and impact. The structural shift from “injection is #1” to “broken access control is #1” reflects the move from monolithic SQL-backends to API-driven, microservice architectures where authorization logic lives in code, not in a query parser.
OWASP 2021 OWASP 2017───────────────── ─────────────────A01 Broken Access Control A01 InjectionA02 Cryptographic Failures A02 Broken AuthenticationA03 Injection A03 Sensitive Data ExposureA04 Insecure Design (new) A04 XXEA05 Security Misconfiguration A05 Broken Access ControlA06 Vulnerable Components A06 Security MisconfigA07 Identification & Auth Failure A07 XSSA08 Software & Data Integrity A08 Insecure DeserializationA09 Security Logging Failure A09 Vulnerable ComponentsA10 SSRF (new) A10 Insufficient LoggingEach entry is a class, not a single bug. A03 Injection covers SQLi, NoSQLi, command injection, LDAP injection, and XPath injection — all of which are separate modules in this handbook (W2, W8, W21).
How It Works
Section titled “How It Works”- Data collection — OWASP surveys AppSec vendors and bug-bounty platforms for: vulnerability category, incidence rate across tested applications, exploitability (via CVSS), and impact. The 2021 corpus was ~500,000 vulnerabilities across 40 firms.
- Categorization — submissions are mapped to a fixed taxonomy (CWE IDs). A01 Broken Access Control alone maps to 34 CWEs (CWE-200, CWE-201, CWE-352, CWE-862, CWE-863…).
- Ranking — four factors: incidence, exploitability (CVSS weighted), impact (technical + business), and detectability. The 2021 list introduced two new categories (Insecure Design, SSRF) precisely because they failed to map cleanly to any 2017 category.
- Mapping to controls — each category references the OWASP ASVS (Application Security Verification Standard), the OWASP Proactive Controls, and the Cheat Sheet series. A01 → ASVS V4 Access Control, Proactive Control C7.
- Tooling alignment — SAST vendors map rule IDs to OWASP categories. Semgrep, Checkmarx, Veracode all emit findings tagged
OWASP A01:2021so a CISO can roll up by OWASP class in a single chart.
Common Techniques
Section titled “Common Techniques”| OWASP A## | Class | Example Bug Class | CWE |
|---|---|---|---|
| A01:2021 | Broken Access Control | IDOR, missing function-level authz | CWE-862 |
| A02:2021 | Cryptographic Failures | Plaintext storage, weak TLS, deprecated hash | CWE-327 |
| A03:2021 | Injection | SQLi, command injection, NoSQLi | CWE-89, CWE-77 |
| A04:2021 | Insecure Design | Missing rate-limit, no business-logic authz | CWE-209 |
| A05:2021 | Security Misconfiguration | Default creds, verbose errors, open S3 | CWE-16 |
| A06:2021 | Vulnerable Components | Log4Shell (CVE-2021-44228), Equifax Struts | CWE-1104 |
| A07:2021 | Identification & Auth Failure | Credential stuffing, no MFA, weak session | CWE-287 |
| A08:2021 | Software & Data Integrity | Unsigned updates, insecure deserialization | CWE-502 |
| A09:2021 | Security Logging Failure | No audit log on auth events | CWE-778 |
| A10:2021 | SSRF | Internal metadata, IMDSv1 abuse | CWE-918 |
Hands-On Commands
Section titled “Hands-On Commands”# Run OWASP ZAP baseline scan against a target — passive only, no payloadszap-cli --zap-url http://localhost:8080 quick-scan -s all -o '-config scanner.level=HIGH' https://example.com
# Nuclei with OWASP Top 10 tag from the public template reponuclei -u https://example.com -t ~/nuclei-templates/http/cves/ -severity critical,high -tags owasp-top-10
# Burp Suite — passive scan rules are tagged with OWASP A01-A10# Professional & Community have the "OWASP Top 10 2021" scan profile# Scanner options → Issues → filter by A## category
# Semgrep with the OWASP Top 10 packsemgrep ci --config p/owasp-top-10 --config p/owasp-top-ten src/
# Quickly inspect headers and TLS posture against ASVS V9 (communications)curl -sI https://example.com | grep -iE 'strict-transport|x-frame|content-security|x-content-type'testssl.sh --severity HIGH https://example.comDetection — Defender View
Section titled “Detection — Defender View”ModSecurity OWASP CRS 4.x is mapped to OWASP categories by the rule-set’s tag:owasp-top-10 metadata. Each rule carries both an OWASP A## tag and a CWE tag:
SecRule ARGS|REQUEST_HEADERS "@rx ..." \ "id:942100, phase:2, t:none, \ tag:'OWASP_TOP_10/A03', tag:'OWASP_CRS/WEAKNESS', \ tag:'CWE-89', ..."Rule family mapping (CRS 4.0):
- 932100 series — RCE / Command Injection → A03, CWE-77
- 942100 series — SQLi → A03, CWE-89
- 941100 series — XSS → (was A07:2017, now folded into A03 client-side)
- 930100 series — LFI/RFI/Path Traversal → A01, CWE-22
- 920300 series — Protocol / request smuggling → A05, CWE-16
- 934100 series — SSRF / Node sandbox → A10, CWE-918
MITRE ATT&CK T1190 — Exploit Public-Facing Application. This single technique is the upstream ATT&CK mapping for nearly every OWASP Top 10 entry.
Sysmon Event ID 1 — ProcessCreate. When a web stack spawns a child process (cmd.exe, /bin/sh, powershell.exe) originating from a web-server parent (w3wp.exe, nginx worker, php-fpm), that is a downstream signal of A03/A05.
Wazuh rule 31100 family — web attacks (SQLi, XSS, RCE) sourced from ModSecurity audit logs forwarded by Filebeat [verify].
Evasion Techniques
Section titled “Evasion Techniques”Category laundering. A single payload that hits three OWASP classes at once will be reported as one by a WAF. Example: a SSRF request to an internal metadata service that returns IAM credentials, used to then call an internal API without authorization — that is A10 → A01 → A03 in one chain. Most detection tooling reports only the first alert. Defense: enable chained-rule alerting in ModSecurity CRS pl1 paranoia level and ship the full transaction log to a SIEM that can correlate.
A05 misconfiguration as a mask. Many A03 injection failures only work because the framework was misconfigured to expose verbose errors (A05). Turning off display_errors in PHP or DEBUG=True in Django removes the oracle without fixing the injection. This is why A05 ranks so high — it is an enabler for A03/A07.
| Evasion | What it defeats | How to detect |
|---|---|---|
Encoding (%2f, double-URL) | Naive keyword WAFs | Use libinjection + decoded byte matching (CRS does this) |
| HPP (HTTP Parameter Pollution) | Single-value rule match | tx.args aggregate across all params |
Case variation (SeLeCt) | Case-sensitive regex | Always use (?i) or pre-lowercase with t:lowercase |
Comment insertion (S/**/ELECT) | Token regex | Strip inline comments pre-match (t:removeComments) |
| Unicode normalization | ASCII-only matchers | Apply t:urlDecodeUni first |
⚠️ What caught me: An internal scan reported “OWASP A06 zero findings” for an app because the SAST tool only scanned the
requirements.txtand the project had migrated to a private Poetry index. The Log4j-equivalent dependency (a private fork ofpython-jose) had a known CVE in its changelog but no public advisory the scanner could ingest. OWASP A06 is hard because the corpus is external to your code. Lesson: vulnerability databases are incomplete by design; SBOM + manual changelog review is the floor, not the ceiling.
Lab Practice
Section titled “Lab Practice”Container: OWASP Juice Shop (bkimminich/juice-shop) — covers all 10 categories with 100+ challenges tagged by OWASP class.
docker run --rm -p 3000:3000 bkimminich/juice-shop# Score board at http://localhost:3000/#/score-boardObjective: solve one challenge in each of the A01–A10 categories and capture the scoreboard completion percentage per category.
Expected flag format: flag{owasp_top10_2021_a04_insecure_design_solved}.
Detection that should fire: any WAF or RASP in front of Juice Shop — ModSecurity CRS, Coraza, OpenRASP — will alert on challenges in A03 (SQLi login bypass), A07 (JWT none-algorithm), and A10 (SSRF via ftp:// URL in the B2B profile).
Interview Questions
Section titled “Interview Questions”Conceptual: why did OWASP demote Injection from #1 in 2017 to #3 in 2021, and what does that say about how the underlying application architecture has changed?
Scenario: a SAST report shows 0 findings for OWASP A06 (Vulnerable Components) but the SBOM lists 12 dependencies with known CVEs. What is the most likely gap, and how would you close it?
Technical: walk through how ModSecurity CRS maps a single SQLi rule to both A03:2021 and CWE-89, and why that dual tagging matters for compliance reporting.
Compare A08:2021 (Software & Data Integrity) with CWE-502 (Insecure Deserialization). Are they equivalent? If not, what is in A08 that is not in CWE-502?
Conceptual: A04 (Insecure Design) was a brand-new category in 2021 and is sometimes criticized as “untestable.” Give one concrete example of an Insecure Design finding that is NOT already covered by A01 or A07.
Related Modules
Section titled “Related Modules”→ W2 (SQL Injection) · W8 (Command Injection) · F11 (Threat Modeling)