Security
The OWASP Top 10 (2021): what changed and why it matters
A logged-in user opens their invoice at GET /api/invoices/4815 and, out of boredom, edits the URL to 4816. It loads — someone else’s invoice, with their name, address, and card last-four. No exploit kit, no SQL, no payload. Just an integer the server trusted because the request had a valid session cookie. This is IDOR, the textbook face of Broken Access Control — and in OWASP’s 2021 data it sat at the top of the list, found in 94% of every application tested.
What the Top 10 actually is
The OWASP Top 10 is not a checklist of bugs — it is a data-driven ranking of the categories of risk that most often appear in real web applications. The 2021 edition was built from contributed data covering more than 500,000 applications across a dozen organizations: eight of the ten categories came straight from that data, and two were added from a community survey to capture risks that tooling is too young to have measured yet. That last detail matters more than it sounds: it is why a category can rank without huge historical numbers behind it.
The single biggest change in 2021 was philosophical. The list reorganized around root causes instead of symptoms. “Sensitive Data Exposure” — the old #3 — described what you saw after a breach. Its replacement, “Cryptographic Failures,” names what actually went wrong: weak crypto, missing TLS, hardcoded keys. The whole list was re-derived against roughly 400 mapped CWEs (up from about 30), so a category now groups a real failure mode you can design against, not an outcome you notice too late.
Broken Access Control: the new #1
Access control answers one question: is this authenticated user allowed to do this specific thing to this specific resource? When the answer is computed wrong — or never computed — you get Broken Access Control. It rose from #5 in 2017 to #1 in 2021, mapping 34 CWEs, with the highest number of occurrences in the dataset of any category. The headline number: 94% of applications tested showed some form of broken access control. It is simultaneously the most common and one of the most serious classes.
Two failure shapes dominate in production:
- IDOR (Insecure Direct Object Reference): the server uses a client-supplied id to fetch a record but never checks that the record belongs to the caller.
GET /api/invoices/4816returns a stranger’s invoice because the query wasWHERE id = ?and notWHERE id = ? AND owner_id = ?. - Missing function-level authorization: the UI hides the admin button, so nobody guards the endpoint. A non-admin who sends
POST /api/admin/users/{id}/promotedirectly gets promoted, because the only “check” was that the link was invisible.
The senior reflex is deny by default: every resource access starts from “no,” and authorization is enforced server-side on the actual record and action — never inferred from a hidden UI element, a JWT claim the client could forge, or the mere presence of a session.
| 2021 rank | Category | Change vs 2017 | What it really means |
|---|---|---|---|
| A01 | Broken Access Control | Up from #5 | 94% of apps; IDOR + missing authz checks |
| A02 | Cryptographic Failures | Renamed from Sensitive Data Exposure | Cause, not symptom: weak crypto, missing TLS |
| A03 | Injection | Down from #1 | Now includes XSS; parameterize everything |
| A04 | Insecure Design | NEW | Threat-model before code; some flaws can’t be patched |
| A05 | Security Misconfiguration | Up from #6 | Default creds, verbose errors, open buckets |
| A06 | Vulnerable & Outdated Components | Up from #9 | Your dependencies’ CVEs are your CVEs |
| A10 | SSRF | NEW (survey-voted) | Server fetches an attacker-chosen URL |
The new design-era categories
Two additions in 2021 mark the field maturing past “scrub the input.” Insecure Design (A04) is the recognition that some vulnerabilities are baked in before a single line is written — a password-reset flow with no rate limit, a checkout that trusts a client-sent price. You cannot patch your way out of a flawed design; the fix is shift-left: threat-model the feature, write abuse cases alongside user stories, and bake the control into the architecture. It is the difference between a coding mistake and a missing security requirement.
SSRF (A10) is the standout for a different reason: it had almost no historical data — it maps essentially a single CWE — yet it ranked, because practitioners voted it in through the community survey. SSRF is when your server can be tricked into making a request to a URL the attacker controls: a “fetch this image” feature pointed at http://169.254.169.254/ to read cloud metadata credentials. Its presence on the list, ahead of better-documented bugs, is the clearest signal that the Top 10 tracks where the field is heading, not just where the old scanners have already been.
Why this works
Why does Injection — the reigning #1 for years — fall to #3 in 2021? Not because it got rarer, but because the tooling got good. ORMs, parameterized queries, and auto-escaping template engines made the common path safe by default, so the average incidence dropped even as the category broadened to absorb XSS. The lesson: a risk falls in the rankings when the safe option becomes the easy option — which is exactly the outcome good design aims for.
How a senior reads the list
The ranking is a prioritization tool, not gospel. A senior reads it as “where is my time best spent,” and access control wins on expected value: it is the most common class and among the most damaging, so it earns the most rigor — server-side checks on every object and every function, written as deny-by-default. Treat the rest as a coverage map: crypto in transit and at rest, parameterized data access, a dependency-update process so A06 doesn’t accumulate silently, hardened configs, and structured security logging so you can even detect the breach you didn’t prevent.
An endpoint `GET /api/invoices/{id}` returns an invoice by id. A user changes the id in the URL and sees someone else's invoice. Pick the correct fix.
Why was 'Sensitive Data Exposure' renamed to 'Cryptographic Failures' in 2021?
A non-admin sends `POST /api/admin/users/7/promote` directly and it succeeds, even though the admin button is hidden in their UI. What category is this, and what's the fix?
Order the 2021 Top 10 categories by their rank, from A01 to A05:
- 1 Broken Access Control (94% of apps; IDOR + missing authz)
- 2 Cryptographic Failures (renamed from Sensitive Data Exposure)
- 3 Injection (now includes XSS; down from #1)
- 4 Insecure Design (new — threat-model before code)
- 5 Security Misconfiguration (default creds, verbose errors)
- 01Explain why Broken Access Control jumped to #1 in 2021 and what 'deny by default' means in code.
- 02What is different about Insecure Design and SSRF, and why does their presence in 2021 signal the field maturing?
The OWASP Top 10 (2021) is a data-driven ranking of risk categories built from 500,000+ real applications, reorganized around root causes instead of symptoms — which is why “Sensitive Data Exposure” became “Cryptographic Failures.” Broken Access Control is the headline: it climbed from #5 to #1, appears in 94% of tested apps, and shows up in production as IDOR and missing function-level authorization. The fix is deny-by-default authorization enforced server-side on every object and action, never inferred from a hidden button or a client-supplied claim. Two new design-era categories — Insecure Design and SSRF — mark the field maturing from “filter bad input” toward “design for least privilege,” with SSRF earning its spot by practitioner vote despite thin historical data. Read the list as a prioritization map: spend the most rigor where expected damage is highest, and treat the rest as coverage you don’t let drift.