OWASP Top 10: A Practical Field Guide for Builders

sumit@askmeidentity.comS

sumit@askmeidentity.com

1 min read1,172 words

The OWASP Top 10 is the most widely-cited shorthand for "the things that actually break web apps." It's not a checklist of exotic exploits — it's the boring, recurring failure modes that show up in real breach reports year after year. If you ship software, these are the categories you'll be measured against by auditors, pen-testers, and (eventually) attackers.

This guide walks through the current Top 10 (the 2021 list, which is still the most recent published edition), explains the risk in plain language, and gives you something concrete to do about each one.


A01:2021 — Broken Access Control

What it is: A user can do something they shouldn't — read another tenant's data, escalate their role, hit an admin endpoint without an admin token.

Why it's #1: It moved up from #5 in the previous edition. 94% of tested applications had some form of broken access control. It's the single most common class of real-world breach.

What to do:

  • Deny by default. Every endpoint should require an explicit policy decision, not "we forgot to add auth here."
  • Enforce authorization on the server, not the UI. Hiding a button is not security.
  • Scope every query to the current user/tenant — don't trust IDs from the request body.
  • Log access-control failures and alert on bursts (someone is enumerating).

A02:2021 — Cryptographic Failures

What it is: Sensitive data exposed because crypto was missing, weak, or misused — plaintext passwords, MD5 hashes, hard-coded keys, TLS misconfiguration.

What to do:

  • Classify data first. You can't protect what you haven't catalogued.
  • Use vetted libraries — never roll your own crypto.
  • Argon2id / bcrypt / scrypt for password hashing. Never SHA-256 alone.
  • TLS 1.2+ everywhere, HSTS enabled, modern cipher suites only.
  • Keys live in a KMS / secret manager, not in source control or env files committed to git.

A03:2021 — Injection

What it is: Untrusted input ends up interpreted as code or commands — SQL injection, OS command injection, LDAP injection, NoSQL injection, and (newly merged in) cross-site scripting (XSS).

What to do:

  • Parameterized queries / prepared statements. Always. ORMs help but don't blindly trust raw-SQL escape hatches.
  • Validate input at the boundary against an allow-list, not a deny-list.
  • Encode output contextually (HTML, attribute, JS, URL — each is different).
  • Use a Content Security Policy that disallows inline scripts.

A04:2021 — Insecure Design

What it is: The architecture itself is flawed — missing rate limits, no threat model, business-logic flows that can be abused even if every line of code is "correct."

What to do:

  • Threat-model new features before writing code. STRIDE is a fine starting framework.
  • Build abuse cases alongside use cases. ("What if someone calls this endpoint 10,000 times?")
  • Rate-limit anything that costs money, sends email/SMS, or touches an external API.
  • Reference architectures (OWASP ASVS, cheat sheets) — borrow, don't invent.

A05:2021 — Security Misconfiguration

What it is: Default credentials still in place, verbose error pages leaking stack traces, S3 buckets set to public, debug mode on in production, missing security headers.

What to do:

  • Infrastructure-as-code with a hardened baseline. Drift detection.
  • Disable / remove unused features, default accounts, sample apps.
  • Security headers as middleware: HSTS, X-Content-Type-Options, Referrer-Policy, CSP, Permissions-Policy.
  • Production builds never ship with debug toolbars or stack traces visible to users.

A06:2021 — Vulnerable and Outdated Components

What it is: A dependency (Log4j, OpenSSL, that one abandoned npm package) has a known CVE and you're still running the vulnerable version.

What to do:

  • Maintain a software bill of materials (SBOM) — you can't patch what you can't see.
  • Automated dependency scanning (Dependabot, Renovate, Snyk, Trivy). Triage weekly.
  • Pin versions, but update them deliberately — pinning without patching is how Log4Shell happened.
  • Subscribe to security advisories for your core stack.

A07:2021 — Identification and Authentication Failures

What it is: Credential stuffing succeeds, MFA isn't enforced, session tokens are predictable or never expire, password reset flows are abusable.

What to do:

  • Use a battle-tested identity provider (Auth0, Okta, Cognito, Keycloak). Don't build login from scratch.
  • Enforce MFA for admin and sensitive roles. Phishing-resistant (WebAuthn/passkeys) where possible.
  • Rate-limit and lockout on failed logins; alert on credential-stuffing patterns.
  • Rotate session tokens on privilege escalation. Short access tokens + refresh tokens, not 30-day JWTs.

A08:2021 — Software and Data Integrity Failures

What it is: You trust code or data without verifying it — unsigned updates, untrusted CI/CD pipelines, deserialization of attacker-controlled payloads, dependency confusion attacks.

What to do:

  • Sign your artifacts (Sigstore, cosign). Verify signatures before deploy.
  • Lock down CI/CD — least-privilege secrets, branch protection, required reviews on workflow files.
  • Never deserialize untrusted input with pickle / Java native serialization / unserialize(). Use JSON or a schema-validated format.
  • Subresource Integrity (SRI) on third-party scripts you load in the browser.

A09:2021 — Security Logging and Monitoring Failures

What it is: A breach happens and you find out 200 days later from a third party. Logs were missing, alerts were silenced, or no one was watching the dashboard.

What to do:

  • Log authentication events, access-control failures, server-side validation failures, and admin actions. Centralize them.
  • Tamper-evident storage — attackers will try to wipe logs.
  • Alert on patterns, not single events (failed-login spikes, mass enumeration, unusual data exfil volumes).
  • Run incident-response tabletops. The first time you read the runbook should not be during the actual incident.

A10:2021 — Server-Side Request Forgery (SSRF)

What it is: Your server fetches a URL provided by the user — and an attacker uses that to hit http://169.254.169.254/ (cloud metadata) or your internal admin panel.

What to do:

  • Allow-list outbound destinations. Deny-listing is fragile (DNS rebinding, IPv6, redirects).
  • Resolve URLs and block private/link-local/loopback ranges before the request.
  • Disable HTTP redirects on internal fetchers, or follow them with the same allow-list applied.
  • Lock down cloud metadata services (IMDSv2 on AWS, hop-limit set to 1).

How to actually use this list

The Top 10 isn't a compliance checklist. It's a map of where attention pays off. A few habits that work:

  1. Pick one category per quarter and run a focused audit. Trying to fix all ten at once is how nothing ships.
  2. Wire the boring controls into CI — dependency scans, secret detection, IaC linting. Humans miss things; CI doesn't get tired.
  3. Threat-model new features as part of the design review, not after the code is merged.
  4. Practice incident response with the same rigor as code review. The breach is when, not if.

The categories shift edition to edition, but the underlying lesson doesn't: most breaches are not zero-days. They're misconfigurations, missing access checks, and unpatched dependencies — the things that are unglamorous to fix and devastating to ignore.


References: OWASP Top 10 — 2021, OWASP ASVS, OWASP Cheat Sheet Series.

0 comments

Comments

Loading comments…

Sign in to leave a comment.