The OWASP Top 10 (2025 Edition): What Changed and How to Fix Each Risk
The OWASP Top 10 is the closest thing web security has to a shared vocabulary, and in 2025 it changed in ways worth paying attention to: two entirely new categories appeared, Security Misconfiguration jumped from #5 to #2, and Server-Side Request Forgery — its own entry in 2021 — got folded back into Broken Access Control. If your mental model or your scanner config still maps to the 2021 list, you are now describing risks with the wrong names and missing two categories outright. The list is not gospel; it is a data-driven snapshot of what is actually getting exploited in real applications. Here is the 2025 list, what moved and why, and the concrete fix for each item.
What Changed From 2021
The reshuffle is driven by OWASP’s analysis of real vulnerability data plus a survey of practitioners. Three structural changes matter most: Software Supply Chain Failures (A03) is a new, broader successor to the old “Vulnerable and Outdated Components,” reflecting that attacks now target build systems and distribution channels, not just outdated libraries; Mishandling of Exceptional Conditions (A10) is brand new, covering error-handling bugs and fail-open logic; and SSRF lost its standalone spot, absorbed into Broken Access Control.
| 2025 | Category | 2021 origin |
|---|---|---|
| A01 | Broken Access Control | A01 (now also absorbs SSRF) |
| A02 | Security Misconfiguration | A05 (up from #5) |
| A03 | Software Supply Chain Failures | New (expands A06 Vulnerable/Outdated Components) |
| A04 | Cryptographic Failures | A02 |
| A05 | Injection | A03 |
| A06 | Insecure Design | A04 |
| A07 | Authentication Failures | A07 (renamed) |
| A08 | Software or Data Integrity Failures | A08 |
| A09 | Security Logging & Alerting Failures | A09 (renamed; “Alerting”) |
| A10 | Mishandling of Exceptional Conditions | New |
2021 2025
-------------------- --------------------
A01 Broken Access Ctrl ───▶ A01 Broken Access Ctrl ◀── A10 SSRF merges in
A02 Cryptographic ╲ A02 Security Misconfig ◀── (was A05, promoted)
A03 Injection ╲ A03 Supply Chain ◀── NEW (grows from A06)
A04 Insecure Design ╲ A04 Cryptographic
A05 Security Misconfig ───╳ A05 Injection
A06 Vulnerable Comps ───╯ A06 Insecure Design
A07 Auth Failures ───▶ A07 Authentication
A08 Data Integrity ───▶ A08 Software/Data Integrity
A09 Logging Failures ───▶ A09 Logging & Alerting
A10 SSRF ──(merged into A01) A10 Mishandling Exceptions ◀── NEW
The takeaway from the movement: the industry’s pain has shifted from “we wrote an injectable query” toward “we trusted something we shouldn’t have” — a misconfigured default, a compromised dependency, an error path that failed open. The new entries reward defense at the boundaries of your system, not just inside your request handlers.
A01: Broken Access Control
Still #1, still the most exploited class of bug: users acting outside their intended permissions. The classic case is an endpoint that trusts an ID from the URL without checking who is asking.
|
|
Because SSRF now lives here, the same “don’t trust attacker-supplied targets” principle extends to outbound requests: if a user controls a URL your server fetches, they can reach your cloud metadata endpoint or internal services.
|
|
Deny by default, enforce authorization on the server (never in the client), and prefer access checks at a central chokepoint over scattering them across handlers.
A02: Security Misconfiguration
The biggest mover, promoted to #2 — because the average system now has far more knobs (cloud IAM, container runtimes, framework defaults, CI/CD), and the defaults are frequently insecure. Default credentials, an exposed admin panel, an S3 bucket set to public, a verbose stack trace handed to an attacker, CORS set to *.
- Change every default credential; disable features and ports you don’t use.
- Return generic error pages in production — never raw stack traces (which ties directly into A10).
- Treat configuration as reviewed, version-controlled artifacts, and scan it:
trivy config,tfsec, orkube-scorecatch the obvious holes before they ship. This is the same discipline covered in container security.
A03: Software Supply Chain Failures (New)
The successor to “Vulnerable and Outdated Components,” widened to cover the whole chain: the dependencies you pull, the build system that assembles them, and the registry that distributes the result. The 2025 framing acknowledges that attackers increasingly compromise upstream — a poisoned npm package, a typosquatted PyPI name, a backdoored build step — rather than waiting for you to run an old version.
|
|
Defenses: pin dependencies with a committed lockfile, pull from a vetted internal registry rather than the public one directly, verify signatures and SLSA provenance, and gate builds in CI/CD on an SBOM diff so a new transitive dependency can’t sneak in unreviewed.
A04: Cryptographic Failures
Was #2 in 2021; the risk is unchanged even if the rank slipped — sensitive data exposed through weak or absent cryptography.
- Use TLS 1.3 in transit (see HTTPS and TLS explained); encrypt sensitive data at rest.
- Hash passwords with Argon2id or bcrypt — never a bare SHA-256, never MD5.
- Don’t roll your own crypto; use vetted libraries and authenticated encryption (AES-GCM, not raw AES).
- Don’t log secrets, and keep keys out of source — manage them with a real secrets manager.
A05: Injection
SQL, NoSQL, OS command, LDAP — untrusted input interpreted as code. The fix is the same as it has been for two decades, and it works: never concatenate input into a command; let the interpreter separate code from data.
|
|
Use parameterized queries / prepared statements everywhere, prefer an ORM’s safe builders, and validate input against an allowlist. For OS commands, pass argument arrays rather than a shell string, and avoid spawning a shell at all where you can.
A06: Insecure Design
Flaws baked into the architecture, where no amount of clean implementation saves you — a password-reset flow with no rate limit, a checkout that trusts a client-side price, tenants that share a trust boundary they shouldn’t.
- Threat model before you build; ask “how would an attacker abuse this flow?” at design time.
- Use secure design patterns: enforce business limits server-side, separate tenants, fail closed.
- Add abuse-case tests alongside functional tests so the design intent is verified, not assumed.
A07: Authentication Failures
Renamed from “Identification and Authentication Failures.” Weak or broken proof of identity: credential stuffing, brittle password rules, guessable session tokens, no MFA.
- Offer MFA and prefer phishing-resistant factors (passkeys/WebAuthn) over SMS.
- Rate-limit and add backoff on login; check passwords against known-breached lists instead of forcing arcane composition rules.
- Generate long, random session IDs; rotate on privilege change; set
Secure,HttpOnly,SameSitecookies and a sane idle timeout.
A08: Software or Data Integrity Failures
Trusting code or data whose integrity you never verified — an auto-update that doesn’t check signatures, deserialization of untrusted objects, a CI pipeline that anyone can inject steps into. This sits one level below A03: where supply chain is about the whole ecosystem, this is about your trust boundaries and verification.
- Verify signatures on updates and artifacts before executing them.
- Never deserialize untrusted data into live objects (Java/Python pickle/PHP are classic footguns); use a data-only format and validate it.
- Lock down who can modify pipeline definitions; treat the pipeline as production infrastructure.
A09: Security Logging & Alerting Failures
Renamed to add “Alerting” — because a log nobody acts on is theater. The 2025 emphasis: capturing security events is necessary but not sufficient; you must alert on them fast enough to respond.
Log (and alert on): authentication successes and failures, access-control denials, input-validation failures, and high-value actions. Then make the logs useful — centralized, tamper-resistant, with enough context to investigate, and wired to alerts that page a human on the patterns that matter. Capturing the event and discovering it three months later in a breach report is the failure this category names.
A10: Mishandling of Exceptional Conditions (New)
The other new entry, and an easy one to overlook: bugs that emerge when something goes wrong — improper error handling, logic that fails open, swallowed exceptions, and abnormal states the code never anticipated. The canonical disaster is an auth check that grants access when it errors instead of denying it.
|
|
Fail closed by default, never leak internal detail in error responses (that overlaps with A02), handle the unexpected explicitly instead of catching-and-ignoring, and make sure a partial failure can’t leave the system in a permissive state.
Testing for All Ten
No single tool covers the list; layer them:
| Technique | Catches | Tools |
|---|---|---|
| SAST (static analysis) | Injection, crypto misuse, insecure patterns | Semgrep, CodeQL |
| DAST (dynamic testing) | Access control, misconfiguration, runtime flaws | OWASP ZAP, Burp |
| SCA (dependency scanning) | A03 supply chain, vulnerable components | osv-scanner, Trivy, Snyk |
| Config / IaC scanning | A02 misconfiguration | tfsec, trivy config, kube-score |
| Penetration testing | Design flaws, chained exploits | Human testers |
Wire SAST and SCA into the pipeline so they gate merges, run DAST against staging, and schedule periodic manual pentests for the logic flaws automation can’t see.
Verdict
The 2025 refresh tells a clear story: the soft spots have moved outward. A decade ago the list was dominated by what you typed into a request handler; today three of the highest-impact categories — Security Misconfiguration at #2, the new Software Supply Chain Failures at #3, and Mishandling of Exceptional Conditions at #10 — are about what your system trusts and how it behaves when something goes wrong. Injection is still here and parameterized queries still fix it, but the marginal risk now lives in your defaults, your dependencies, and your error paths.
Use the list the way it’s meant to be used: as a prioritized baseline, not a compliance checklist. Get the durable habits right — deny by default and authorize server-side, treat configuration and dependencies as reviewed artifacts, fail closed and alert on what matters — and you cover most of all ten at once. Then layer SAST, SCA, DAST, and the occasional human pentest so the categories you can’t reason about in your head get caught by something that can. The names changed in 2025; the discipline didn’t.
Sources
- OWASP Top 10:2025 — official project site
- OWASP Top 10:2025 — Introduction and methodology
- OWASP Top 10:2021 — for comparison
- OWASP — A03:2025 Software Supply Chain Failures
- OWASP Cheat Sheet Series — Top Ten index
- OWASP ZAP — dynamic application security testing
- OSV-Scanner — dependency vulnerability scanning
- SLSA — Supply-chain Levels for Software Artifacts
Comments