# The OWASP Top 10, Explained

> What OWASP and the Top 10 actually are - a shared checklist and vocabulary for the most common, most damaging ways web apps get broken into, and how to use it without fooling yourself into a false sense of security.


---

# The OWASP Top 10, Explained

Somebody on your team says "we should check this against the OWASP Top 10," and you nod - but quietly, you're not sure what that *is*. A standard? A law? A scanner you're supposed to run? You've seen the acronym in security audits, compliance checklists, and job descriptions, always assumed you already know it.

Here's the relief: the OWASP Top 10 is not a test you can fail and not a tool you have to install. It's a **field guide to the usual suspects** - the handful of mistakes that account for most real-world break-ins, written down so the whole industry can point at the same list and use the same words.

## How to read this

- **Just need the lay of the land?** Phase 1 explains what OWASP and the Top 10 are in five minutes, and Phase 2 has a scannable table of the big categories - skim that and you'll hold your own in any security conversation.
- **Want it to actually stick?** Read in order. Each phase builds on the last: what the list *is*, what's *on it*, and how to *use it without lying to yourself*.

## The phases

1. **[What OWASP & the Top 10 Are](01-what-owasp-is.md)** - the nonprofit, the list, and why "a shared checklist and vocabulary" is the whole point.
2. **[The Big Categories, in Plain English](02-the-big-categories.md)** - a walk through the recurring risks, each as a one-line "what it is + the fix," with a scannable table.
3. **[How to Actually Use It](03-how-to-use-it.md)** - it's a checklist, not a guarantee: thread it into design, code review, and dependency updates, and avoid the trap of "we checked it once."

> Deep dives on individual risks live in their own guides - [SQL injection and XSS](/guides/sql-injection-and-xss), [authentication vs. authorization](/guides/auth-vs-authz), and [what security actually means](/guides/what-security-means). This guide is the map that points to all of them.


---

# What OWASP & the Top 10 Are

Before we look at a single vulnerability, let's clear up the confusion that trips up almost everyone the first time. The OWASP Top 10 sounds like it should be one specific thing - a piece of software, a certification, a rule you have to obey. It's none of those, and getting the mental model right *first* is what makes the actual list make sense.

## What OWASP actually is

**What it actually is.** OWASP is the **Open Worldwide Application Security Project** - a nonprofit foundation that publishes free, vendor-neutral resources about software security. Think of it as a community-run public library for application security: documentation, tools, cheat sheets, and guides, all open and free, maintained by volunteers and contributors around the world.

**Why people get this wrong.** Because the name shows up next to scary audit language, people assume OWASP is a company selling a product, or a government body issuing regulations. It's neither. Nobody can "sell you OWASP," and OWASP can't fine you. It's a body of freely available knowledge - and the Top 10 is its single most famous publication.

💡 **Key point.** OWASP is the organization. The Top 10 is one document that organization produces. Keep those two separate in your head and half the confusion evaporates.

## What the Top 10 actually is

**What it actually is.** The OWASP Top 10 is a **list of the ten broad categories of security risk that most commonly and most seriously affect web applications.** It's compiled from real-world data - vulnerabilities found across huge numbers of real applications - plus input from security practitioners about what's hurting people in practice.

The two words that matter most are **categories** and **risk**.

- It's not a list of ten specific bugs. Each entry is a *family* of related problems. "Injection," for example, covers SQL injection, command injection, and several cousins - many distinct bugs under one banner.
- It ranks by **risk**, which blends how common a problem is with how much damage it does when exploited. A flaw that's everywhere and catastrophic ranks above one that's rare and minor.

📝 **Terminology.** A *vulnerability* is a specific weakness in one app (a particular login form that doesn't check permissions). A *category* (or "risk category") is the named family that weakness belongs to (Broken Access Control). The Top 10 lists categories; your code has vulnerabilities that fall *into* those categories.

**Why people get this wrong.** Newcomers expect a checklist of literal bugs they can grep for. Instead they find ten broad headings and feel let down - "this is vague." It's broad *on purpose*. Specific bugs come and go; the underlying mistakes ("you trusted input you shouldn't have," "you forgot to check who's asking") repeat across every framework and decade. The categories are durable in a way a list of individual bugs never could be.

## The mental model: a field guide to the usual suspects

Here's the picture to carry around. A field guide to birds doesn't list every bird that has ever existed - it shows you the ones you're actually likely to see, with enough detail to recognize each on sight. The OWASP Top 10 is a field guide to the *usual suspects* in web app break-ins: the attacks you're genuinely likely to face, described so you can recognize them in your own code before an attacker recognizes them first.

```mermaid
flowchart TD
  owasp["OWASP<br/>(nonprofit - publishes free security resources)"]
  top10["The Top 10<br/>(a field guide to the ~10 most common risk CATEGORIES)"]
  vulns["many real vulnerabilities in real apps"]
  owasp -- produces --> top10
  top10 -- "each category covers" --> vulns
```

That last line is the real value, and it's worth saying plainly: the Top 10's biggest gift isn't the ranking - it's that it gives the whole industry a **shared checklist and a shared vocabulary.** When a pentester writes "Broken Access Control" in a report, your team knows exactly what family of problem they mean, where to look, and roughly how bad it is. Before shared lists like this, every report invented its own terms and every team argued past each other.

## A periodically-updated list - check the source

**What it does in real life.** OWASP revises the Top 10 every few years as the data and the threat landscape shift. Categories get renamed, merged, split, or re-ranked between editions - something near the top one year might drop, and new concerns (like server-side request forgery) get promoted in as they become more common.

⚠️ **Gotcha.** Don't memorize one edition's exact ordering as if it were permanent truth - and be wary of blog posts quoting an old version. The categories described in the next phase reflect the most recent published list at the time of writing; for the current edition, the precise ranking, and the official write-ups, always go to the source: **[owasp.org](https://owasp.org)**.

**Why this saves you later.** When a colleague references "A03" or "the new SSRF entry," you'll know that's edition-specific shorthand, not gospel - and you'll instinctively check which version they mean instead of arguing from a stale memory.

## Recap

1. **OWASP** is a nonprofit that publishes free, vendor-neutral application-security resources - not a tool, company, or regulator.
2. **The Top 10** is OWASP's list of the ten broad *categories* of the most common and impactful web app security risks.
3. It ranks by **risk** (how common × how damaging), and each entry is a *family* of related vulnerabilities, not a single bug.
4. The mental model: a **field guide to the usual suspects** - and its real value is a **shared checklist and vocabulary** for the whole industry.
5. It's **updated every few years**; check [owasp.org](https://owasp.org) for the current edition rather than trusting any one ranking as permanent.


---

# The Big Categories, in Plain English

Now the payoff. These are the families you'll keep meeting for the rest of your career, and once you can describe each in a sentence, the whole list stops being intimidating. Almost every category comes down to one of a few human mistakes: *trusting input you shouldn't, forgetting to check who's asking, or leaving a default switched on.*

Skim the table first to get the shape, then read the notes underneath for the ones worth a little more.

> 💡 These are the recurring headings from the most recent published list at the time of writing. Names and ordering shift between editions - see [owasp.org](https://owasp.org) for the current version. We're not numbering them here on purpose, so you don't memorize an ordering that changes.

## The scannable table

| Category | What it is, in one line | The fix, in one line |
|---|---|---|
| **Broken Access Control** | A logged-in user can reach data or actions that aren't theirs (e.g. change `/orders/123` to `/orders/124` and see someone else's order). | Check *who's allowed* on the **server** for every request - never trust the client or a hidden field. |
| **Cryptographic Failures** | Sensitive data is left readable - not encrypted, weakly hashed, or sent in the clear. | Encrypt data in transit (HTTPS) and at rest; hash passwords with a strong, slow algorithm; don't roll your own crypto. |
| **Injection** | Untrusted input is fed straight into a query or command, so the attacker's text becomes part of your code (SQL injection, command injection, XSS). | Use parameterized queries and proper output encoding; never build commands by gluing strings together. |
| **Insecure Design** | The *design* is flawed before a line is written - a missing rate limit, a "recover password by guessing a 4-digit code" flow. | Threat-model early; design the security controls in, don't bolt them on after. |
| **Security Misconfiguration** | The software is fine but set up wrong - default passwords left on, debug mode in production, an open admin panel. | Harden defaults, turn off what you don't use, and keep environments configured the same way deliberately. |
| **Vulnerable & Outdated Components** | A library or dependency you pulled in has a known hole - and you never updated it. | Track your dependencies, patch promptly, and remove what you don't need. |
| **Identification & Authentication Failures** | The "who are you?" step is weak - guessable passwords, no protection against brute force, broken session handling. | Strong password rules, multi-factor auth, rate-limited logins, and safe session management. |
| **Server-Side Request Forgery (SSRF)** | Your server can be tricked into making requests *on the attacker's behalf* - fetching a URL they control, reaching internal systems they can't. | Validate and allow-list outbound URLs; don't let user input decide what your server connects to. |

That table is genuinely enough to follow most security conversations. The notes below add the mental model for the few that bite hardest.

## Broken Access Control - "are you allowed to do that?"

**What it actually is.** Two questions get confused constantly: *who are you?* (authentication) and *what are you allowed to do?* (authorization). Broken Access Control is the second one failing - you're correctly logged in, but the app lets you do something you shouldn't.

**A real example.**
```console
$ curl https://shop.example.com/api/orders/1042 -H "Authorization: Bearer <my-token>"
{"order_id":1042,"customer":"someone.else@example.com","total":"$240.00","items":[...]}
```
*What just happened:* You're logged in as yourself, but order `1042` belongs to a different customer. The server checked that you're *a* valid user, but never checked that you're the user who *owns this order*. Change the number, see somebody else's data. This is one of the most common and damaging categories precisely because it's so easy to leave the second check out.

**The gotcha.** Hiding a button in the UI is not access control. The attacker isn't using your UI - they're sending raw requests with `curl`. Every authorization decision has to happen on the **server**, on every request, no exceptions.

> ⏭️ The full "who are you vs. what can you do" distinction has its own home: [authentication vs. authorization](/guides/auth-vs-authz).

## Injection - "your input became my code"

**What it actually is.** Injection happens when data the user supplied gets treated as *instructions* instead of *content*. You meant their input to be a search term; the database read it as a command.

**A real example.**
```text
   Your code:    "SELECT * FROM users WHERE name = '"  +  input  +  "'"

   Normal:       input = "alice"
                 → SELECT * FROM users WHERE name = 'alice'

   Attack:       input = "' OR '1'='1"
                 → SELECT * FROM users WHERE name = '' OR '1'='1'
                                                        └─ always true → returns everyone
```
*What just happened:* By gluing user input directly into the query string, you let the attacker close your quote and add their own logic. `'1'='1'` is always true, so the query returns every row. The fix - **parameterized queries** - sends the input as a separate value the database always treats as data, never as SQL. Cross-site scripting (XSS) is the same idea aimed at the browser: untrusted input becomes executable HTML/JavaScript on the page.

> ⏭️ Both SQL injection and XSS get the full walkthrough in [SQL injection and XSS](/guides/sql-injection-and-xss).

## SSRF - "make my server do your bidding"

**What it actually is.** Server-Side Request Forgery is when your server fetches a URL, and the attacker controls that URL. They can't reach your internal network - but your server can, so they use *your server* as a proxy to poke at things they're not supposed to see (internal admin panels, cloud metadata endpoints, databases behind your firewall).

**The gotcha.** It looks innocent: a feature that fetches a user-supplied image URL, or a webhook that calls back to an address the user typed. The moment user input decides where your server connects, you have a potential SSRF. Allow-list the destinations; don't let arbitrary input steer outbound requests. SSRF is a good example of the list evolving - it earned its own top-level entry as cloud architectures made it far more dangerous than it used to be.

## The pattern underneath all of them

Step back and you'll see most of these rhyme:

```mermaid
flowchart LR
  m1["Trusting input you shouldn't"] --> c1["Injection, SSRF, Insecure Design"]
  m2["Forgetting to check the asker"] --> c2["Broken Access Control, Auth Failures"]
  m3["Leaving a default switched on"] --> c3["Security Misconfiguration, Outdated Components"]
  m4["Failing to protect the data"] --> c4["Cryptographic Failures"]
```

You don't have to memorize ten unrelated facts. You have to internalize a few habits of suspicion - and the Top 10 is the checklist that reminds you which suspicions to have *where*.

## Recap

1. Most categories reduce to a few human mistakes: **trusting input**, **skipping the "are you allowed?" check**, or **leaving defaults on**.
2. **Broken Access Control** = you're logged in but reach things that aren't yours; check authorization on the server, every request.
3. **Injection** = user input becomes code; use parameterized queries and output encoding.
4. **SSRF** = your server is tricked into making requests for the attacker; allow-list outbound destinations.
5. The full table covers the rest - and the deeper dives live in linked guides on [injection/XSS](/guides/sql-injection-and-xss) and [auth vs. authz](/guides/auth-vs-authz).


---

# How to Actually Use It

You've got the map. The last question is the one that actually keeps apps safe: *what do you do with it on a Tuesday?* The trap here is treating the Top 10 like a final exam - run through it once, tick the boxes, declare victory. That's exactly the mindset that gets teams breached. The list is a **living checklist**, not a certificate - here's how to thread it into work that's already happening, so it protects you continuously instead of once.

## Thread it into the three places work already happens

You don't need a separate "security phase." You need the Top 10 present at three moments you already have.

**At design time.** Before you build a feature, ask the Top 10's questions of the *plan*: Who's allowed to do this, and where do we check it? What user input do we trust, and should we? What happens if someone hammers this endpoint? This is how you catch **Insecure Design** - the flaws you can't patch later because they're baked into the shape of the thing. Designing the control in costs minutes; retrofitting it costs a rewrite.

**At code review.** Make the relevant categories part of how you read a diff. A reviewer with the list in mind sees the string-concatenated query (Injection), the missing ownership check (Broken Access Control), the user-supplied URL the server fetches (SSRF).

```mermaid
flowchart LR
  diff["Reviewing this diff,<br/>run the relevant suspicions"]
  diff --> q1["touches a DB query?<br/>→ is it parameterized? (Injection)"]
  diff --> q2["touches user data/IDs?<br/>→ does it check ownership? (Broken Access Control)"]
  diff --> q3["touches login/sessions?<br/>→ rate-limited? MFA? safe cookies? (Auth Failures)"]
  diff --> q4["makes an outbound call?<br/>→ is the destination trusted? (SSRF)"]
  diff --> q5["added a dependency?<br/>→ known CVEs? still maintained? (Vulnerable Components)"]
```

**At dependency-update time.** A huge share of real breaches come through **Vulnerable & Outdated Components** - a library with a publicly known hole that nobody updated. This is the least glamorous and most cost-effective security work you'll ever do: keep your dependencies patched.

**A real example.**
```console
$ npm audit
# npm audit report

ws  <8.17.1
Severity: high
ws affected by a DoS when handling a request with many HTTP headers
fix available via `npm audit fix`
1 high severity vulnerability
```
*What just happened:* The tooling cross-referenced your installed packages against a public database of known vulnerabilities and found one you'd never have spotted by reading your own code - the bug is in someone else's library. Most ecosystems have an equivalent (`pip-audit`, `cargo audit`, `govulncheck`, GitHub's Dependabot). Wiring one into CI turns "Vulnerable Components" from a landmine into a routine chore.

## Defense in depth - no single check is the wall

**What it actually is.** Defense in depth means layering protections so that when one fails - and one always eventually fails - another still stands. The Top 10 is one layer: a list of the most likely failures to guard against. It is not the whole wall.

**Why this matters.** A single control is a single point of failure. Validate input *and* use parameterized queries *and* enforce least privilege on the database account, so that a slip in one place doesn't hand over everything. The Top 10 tells you *which* layers are worth having; defense in depth is the principle that you want several of them.

> ⏭️ For the bigger picture of what "being secure" even means - threat models, trade-offs, and why there's no such thing as "done" - see [what security actually means](/guides/what-security-means).

## The trap: "we checked the Top 10, so we're secure"

This is the single most important warning in the guide, so it gets stated bluntly.

⚠️ **Gotcha.** The Top 10 is a floor, not a ceiling. It covers the *most common* risks - by definition, not *all* of them. "We reviewed against the Top 10" means "we checked for the usual suspects," which is genuinely valuable and absolutely not the same as "we are secure." Treating a one-time pass as a guarantee is how teams get comfortable right before they get breached.

⚠️ **Gotcha.** It's a *living* list, and so is your app. New dependencies arrive with new holes; new features add new attack surface; OWASP itself updates the list every few years. A security review is a snapshot of one moment. Re-run your suspicions as the code and the list both change - and keep those dependencies patched, because that clock never stops.

## Go deeper at the source

When you need specifics - exactly how to defend a given category, with concrete code patterns - OWASP publishes **Cheat Sheets**: focused, practical how-to pages for individual topics (input validation, password storage, session management, and many more). The current Top 10 and the full Cheat Sheet Series both live at **[owasp.org](https://owasp.org)**, free. The list in this guide tells you *what* to worry about; the cheat sheets tell you *exactly how* to fix each one.

## Recap

1. The Top 10 is a **checklist, not a guarantee** - it's the floor, never the ceiling.
2. Thread it into work you already do: **design** (catch Insecure Design early), **code review** (run the relevant suspicions on every diff), and **dependency updates** (patch known holes).
3. Wire a dependency scanner into CI so **Vulnerable & Outdated Components** becomes a routine chore, not a landmine.
4. Lean on **defense in depth** - layer controls so no single failure is fatal; see [what security means](/guides/what-security-means).
5. Never treat "we checked it once" as "we're secure"; re-check as the app and the list evolve, and use the OWASP **Cheat Sheets** at [owasp.org](https://owasp.org) for the how-to.
