OWASP Top 10

Almost everyone in security can name it. Far fewer can say what it actually is. It is not a list of bugs to grep for — it is the ten ways web applications most often get broken, ranked from the wreckage of real breaches. Here is how that list gets built, what it says, and how to make it do real work instead of sitting in a compliance binder.

Almost everyone in security can name it. Far fewer can say what it actually is. It is not a list of bugs to grep for — it is the ten ways web applications most often get broken, ranked from the wreckage of real breaches. Here is how that list gets built, what it says, and how to make it do real work instead of sitting in a compliance binder.

9 min read Visual + practical 2021 & 2025

The single most common mistake people make with the OWASP Top 10 is to treat it like a vulnerability scanner's output — a tidy enumeration of bugs you tick off one by one. It isn't that. It's a list of risk categories: ten broad failure modes that, year after year, account for most of the damage done to web applications. Each entry is an umbrella covering dozens of specific weaknesses. "Injection" alone gathers SQL injection, command injection, ORM injection, LDAP injection and cross-site scripting under one heading. So the right way to read the list is not "do I have these ten bugs?" but "which of these ten kinds of failure is my application exposed to, and how badly?"

What it is, and why it exists

OWASP — the Open Worldwide Application Security Project — is a nonprofit that publishes free, vendor-neutral security guidance. The Top 10 is its flagship document: a short, opinionated ranking of the most critical risks facing web applications, refreshed roughly every three to four years. The first edition landed in 2003; the ones people quote today are 2017, 2021, and the latest, 2025.

It exists because security teams drown in detail. There are thousands of distinct weakness types catalogued in MITRE's CWE list — far too many to brief a developer on, let alone a board. The Top 10 compresses all of that into a number a human can hold in their head. It became the lingua franca of AppSec: when an auditor, a PCI-DSS requirement, or a job description says "covers the OWASP Top 10," everyone in the room knows roughly what's meant. That shared shorthand is its real value — and also its biggest trap, because shorthand invites lazy thinking.

How the list is actually built

This is the part most people skip, and it's the part that makes the list trustworthy. OWASP doesn't rank the categories by gut feel. It blends two very different signals:

Data, for eight of the ten slots. Security vendors and testing firms contribute anonymized findings — for 2021 that was on the order of half a million applications, mapped to specific CWEs. OWASP measures each category by how many applications were found to have at least one instance (its incidence rate), not by raw bug count, so that one noisy scanner can't flood the rankings. It also weights each category by exploitability and impact. Pure data-driven selection has a blind spot, though: tools can only find what tools already know how to look for, so emerging risks are invisible to it.

A practitioner survey, for the other two slots. To catch what the scanners miss, OWASP runs an open community survey asking working testers what they're worried about now but isn't yet showing up in the data. That's how Insecure Design and SSRF entered the 2021 list — not because the numbers demanded it, but because the people doing the work flagged them as rising threats ahead of the curve.

So the Top 10 is a deliberate hybrid: mostly evidence, partly foresight. That's why it's more than a popularity contest, and why it occasionally promotes something the raw counts wouldn't.

A tour of the 2021 list

The 2021 edition is still the one most tools, training, and contracts are written against, so it's worth knowing cold. Step through all ten — rank, name, and what each one really means in one line:

And here's roughly what that list looks like on the source itself — the canonical page every AppSec engineer has open in a tab:

https://owasp.org/Top10/
OWASP Top 10:2021
A01  Broken Access Control
A02  Cryptographic Failures
A03  Injection
A04  Insecure Design  ← new
A05  Security Misconfiguration
A06  Vulnerable and Outdated Components
A07  Identification and Authentication Failures
A08  Software and Data Integrity Failures  ← new
A09  Security Logging and Monitoring Failures
A10  Server-Side Request Forgery (SSRF)  ← new

A01: Broken Access Control, up close

It sits at number one for a reason. When OWASP crunched the 2021 data, more applications had an access-control flaw than any other category — it showed up in the majority of everything tested. The idea is simple: access control decides who is allowed to do what, and it's broken whenever the server trusts the client to police itself. The classic shape is the IDOR — Insecure Direct Object Reference — where the app checks that you're logged in but never checks that the record you asked for is actually yours.

You don't need a fancy exploit to find it. You log in as yourself, watch your own traffic, and change a number. Here's the whole attack in one request/response pair as it'd look in Burp Repeater:

Burp Suite — Repeater
Request
GET /api/account/1002 HTTP/1.1
Host: bank.example
Authorization: Bearer 
Accept: application/json

# alice's real id is 1001.
# she just typed 1002.
Response
HTTP/1.1 200 OK
Content-Type: application/json

{"id":1002,"owner":"victim",
 "name":"Bob Carter",
 "balance":"$84,210.55",
 "iban":"DE89 3704 0044 0532 0130 00"}

The server happily returned Bob's account to Alice. It authenticated her — that Bearer token is genuinely hers — but it never authorized the specific object. Authentication asks "who are you?"; authorization asks "are you allowed to touch this?" Broken Access Control is what happens when an app does the first and forgets the second. Walk it through:

1Log in as your own user and capture a request that fetches your data, e.g. GET /api/account/1001.
2Send it to Repeater and change the object reference — bump 1001 to 1002 (or try negative, very large, and other users' IDs).
3Read the response. A 200 with someone else's data — instead of a 403 Forbidden — is a confirmed IDOR.
4Escalate the pattern to writes (PUT/DELETE), to admin-only routes, and to forced browsing of paths your role shouldn't reach.

The fix is unglamorous and absolute: enforce authorization on the server, for every request, against the authenticated identity — never trust an ID, role, or flag that came from the client. Deny by default, centralize the checks so they can't be forgotten on a new endpoint, and test object ownership the way an attacker would: by tampering.

A03: Injection, the old monster

Injection is the category that taught the industry to fear user input. It happens when untrusted data gets spliced into a command or query — SQL, a shell, an LDAP filter, an HTML page — and the interpreter on the other end can't tell your data apart from the developer's code. For two decades it sat at number one. It's still in the top handful, which tells you how stubborn it is.

The canonical example is a login query built by string concatenation:

classic SQL injection
# the vulnerable code builds SQL by gluing strings together:
query = "SELECT * FROM users WHERE name = '" + name + "'"

# the attacker types this into the 'name' field:
' OR '1'='1' --

# so the database actually runs:
SELECT * FROM users WHERE name = '' OR '1'='1' --'
# '1'='1' is always true, '--' comments out the rest.
# result: every row returned, auth bypassed.

The lesson the industry eventually internalized is that escaping quotes is a losing arms race. The real fix changes the architecture: parameterized queries (prepared statements) send the code and the data to the database on separate channels, so the input can never be parsed as SQL no matter what it contains. Same principle everywhere else — use safe APIs that keep data out of the command plane, validate input against an allow-list, and, for cross-site scripting, encode output for the exact context it lands in. This is also why the 2021 edition folded XSS into Injection: it's the same root cause wearing a different hat.

What changed across the versions

The rankings move because the threat landscape moves, and watching them move is more instructive than any single snapshot. The two big stories are the rise of access control and the long, slow fall of injection from its throne:

From 2017 to 2021: Broken Access Control climbed from #5 to #1. Injection — number one for over a decade — slid to #3 as frameworks finally made parameterized queries the default. Two brand-new categories appeared: Insecure Design (the recognition that you can't patch your way out of a fundamentally flawed architecture) and SSRF (pushed up the agenda by cloud metadata endpoints and internal service meshes). XSS was absorbed into Injection; XXE was folded into Security Misconfiguration.

The 2025 edition — the eighth installment, finalized at the end of the 2025 cycle — pushed harder on a single theme: prefer root causes over symptoms. Broken Access Control held #1. Security Misconfiguration surged from #5 to #2, reflecting how much of modern risk lives in cloud and default settings. The headline addition is A03: Software Supply Chain Failures, a major expansion of the old "Vulnerable and Outdated Components" to cover the integrity of the whole build-and-distribution pipeline — the world after SolarWinds and Log4Shell. A second new entry, A10: Mishandling of Exceptional Conditions, captures the bugs that hide in error handling and code that fails open. And SSRF, a standalone category in 2021, was merged back into Broken Access Control — OWASP's view being that, at root, SSRF is an access-control problem.

How to actually use it

A poster of the Top 10 on the wall protects nothing. The list earns its keep only when you turn it into a workflow — map your app to the categories, fix the worst first, and wire the checks into the places where code gets written and shipped:

1Map your features to the categories. Walk every endpoint and ask which of the ten risks it touches — an account API is screaming A01; a search box is A03; a dependency manifest is the supply-chain category.
2Fix by risk, not by alphabet. Start at the top. A01 is #1 because it's both common and devastating — earn that before polishing anything lower.
3Bake it into design. Threat-model new features against the categories before they're built, so you're not retrofitting access control onto a shipped API.
4Automate it in CI. SAST for injection patterns, DAST against running endpoints, and software-composition analysis (SCA) on every dependency — fail the build on new high-severity findings.
5Re-test and watch. Pen-test the way an attacker would (tamper, don't tick boxes), and make sure logging and alerting would actually catch the attempt — that's a Top 10 category too.

One honest caveat: the Top 10 is a floor, not a ceiling. It's the awareness document. When you need real depth — concrete test cases, secure-coding rules — graduate to the OWASP ASVS (Application Security Verification Standard) and the Testing Guide. The Top 10 tells you what to worry about; those tell you exactly what to do about it.

The 2021 list, at a glance

RankCategoryOne concrete example
A01Broken Access ControlIDOR: GET /api/account/1002 returns another user's account
A02Cryptographic FailuresPasswords stored unsalted / in plaintext, or traffic served over plain HTTP
A03InjectionSQLi via ' OR '1'='1' -- in a login form; XSS lives here too
A04Insecure DesignA "forgot password" flow with no rate limit or lockout by design
A05Security MisconfigurationDefault admin creds, verbose stack traces, an open S3 bucket
A06Vulnerable & Outdated ComponentsRunning a Log4j version exposed to Log4Shell (CVE-2021-44228)
A07Identification & Auth FailuresNo MFA, allowing credential stuffing with breached password lists
A08Software & Data Integrity FailuresA poisoned build pipeline ships a backdoored update (SolarWinds)
A09Logging & Monitoring FailuresA breach goes undetected for months because nothing was logged
A10Server-Side Request ForgeryApp fetches an attacker URL, hitting the cloud metadata endpoint (Capital One)
The right way to read itThe Top 10 is a risk awareness document, not a pass/fail checklist and not a standard you can certify against. Use it to start conversations, prioritize effort, and brief non-specialists — then descend into OWASP ASVS and the Testing Guide for the verifiable detail. Pin your work to the version your contracts and tools actually reference (still 2021 for most), but read 2025 to see where the puck is heading: supply chain, misconfiguration, and access control everywhere.
The gistThe OWASP Top 10 is the ten most critical risk categories for web apps — not a bug list — compiled from breach data for eight slots and a practitioner survey for two, refreshed every three to four years. In 2021, Broken Access Control (A01) sits at the top because it's everywhere and brutal: log in as yourself, change an ID, and read someone else's record. Injection (A03) is the fading old monster, beaten by parameterized queries. The 2025 edition keeps A01 on top, vaults Security Misconfiguration to #2, adds Software Supply Chain Failures and Mishandling of Exceptional Conditions, and merges SSRF into access control. Don't frame it — map your app to it, fix the top risks first, and bake the checks into design and CI.
Reactions

Related Articles