# OWASP Top 10: 2025 vs 2021 – What Changed and Why You Should Care

OWASP Top 10: 2025 vs 2021 – What Changed and Why You Should Care

Posted: November 20, 2025


TL;DR for the Speed Readers 🏃‍♂️💨

The OWASP Top 10:2025 Release Candidate just dropped on November 6th, and folks, it’s spicier than your DevOps team’s Slack after a Friday production deploy. We’ve got:

  • Two fresh faces: Software Supply Chain Failures (#3) and Mishandling of Exceptional Conditions (#10)
  • One consolidation: SSRF got absorbed into Broken Access Control (because let’s be real, it always was about access control)
  • Some serious reshuffling: Security Misconfiguration jumped from #5 to #2 like it hit the gym
  • 589 CWEs analyzed across 248 categories (up from ~400 in 2021)
  • Data from 2.8 million applications (yes, MILLION with an M)

The Side-by-Side Showdown 📊

2021 Position 2021 Category 2025 Position 2025 Category Status
A01 Broken Access Control A01 Broken Access Control 👑 Still King
A02 Cryptographic Failures A04 Cryptographic Failures ⬇️ Dropped 2
A03 Injection A05 Injection ⬇️ Dropped 2
A04 Insecure Design A06 Insecure Design ⬇️ Dropped 2
A05 Security Misconfiguration A02 Security Misconfiguration ⬆️ Up 3 spots!
A06 Vulnerable and Outdated Components A03 Software Supply Chain Failures 🔄 Evolved
A07 Identification and Authentication Failures A07 Authentication Failures 📛 Name Change
A08 Software and Data Integrity Failures A08 Software or Data Integrity Failures ↔️ No Change
A09 Security Logging and Monitoring Failures A09 Logging & Alerting Failures 📛 Refined
A10 Server-Side Request Forgery (SSRF) Merged into A01 Broken Access Control 🔗 Consolidated
New A10 Mishandling of Exceptional Conditions ✨ Fresh Entry

The Winners: Who Climbed the Charts 📈

🥈 A02: Security Misconfiguration (Previously #5)

The Glow-Up: This category said “hold my beer” and jumped from #5 to #2.

The Numbers: Now affecting 3.00% of tested applications with 16 different CWEs.

Why the Jump?:

  • Cloud infrastructure is complex AF
  • Kubernetes configs are basically a minefield
  • Default credentials still exist in 2025 (I know, I’m disappointed too)
  • S3 buckets continue to be more open than a 7-Eleven

Real Talk: This is the “somebody left the keys in the ignition” vulnerability. It’s not fancy, it’s not sexy, but it’s everywhere. Think of all those AWS security groups with 0.0.0.0/0 on port 22. Yeah, you know the ones.

# POV: You're auditing cloud infrastructure
aws s3 ls s3://totally-not-public-bucket --no-sign-request
# Output: *dumps entire user database*
# Security team: surprised_pikachu.jpg

The Newcomers: Fresh Blood 🆕

🆕 A03: Software Supply Chain Failures

The Evolution: This isn’t just “Vulnerable and Outdated Components” with a new haircut. This is the category’s final form after training in the hyperbolic time chamber.

What Changed?:

  • Old thinking (2021): “Are you using old libraries with CVEs?”
  • New thinking (2025): “Is literally anyone in your dependency chain compromised?”

Scope Expansion:

  • 🎯 Third-party dependencies (duh)
  • 🔨 Build systems and CI/CD pipelines
  • 📦 Package repositories (looking at you, npm)
  • 🚚 Distribution infrastructure
  • 🤝 Compromised maintainers
  • 💉 Malicious packages masquerading as legit

Why It Matters: Remember SolarWinds? Log4Shell? The xz backdoor attempt? These weren’t “oops we used an old library” problems. These were “our entire supply chain is a trust exercise” problems.

This category acknowledges that modern attacks don’t start with your code—they start three dependencies deep in a library you’ve never heard of, maintained by one unpaid dev, with commit access shared via a Post-It note.

Pro Tip:

# Your dependency tree probably looks like this
your-app
└── some-framework
    └── helpful-util
        └── string-leftpad  # 347 weekly downloads
            └── crypto-lib  # Last updated 2019
                └── 💀 Literally a skeleton maintaining this

🆕 A10: Mishandling of Exceptional Conditions

The New Kid: This is the vulnerability equivalent of “what could go wrong?” followed immediately by something going wrong.

What It Covers (24 CWEs worth):

  • 🚨 Improper error handling
  • 🤔 Logical errors in exception flows
  • 🔓 Failing open instead of closed
  • 💥 Race conditions
  • 🎲 Unhandled edge cases

The Classic Scenario:

try:
    authenticate_user(username, password)
    grant_access()
except DatabaseException:
    # TODO: Handle this properly
    pass  # 💀 Famous last words
    grant_access()  # 🚨 YOLO mode activated

Why It’s Its Own Category Now: OWASP noticed that when systems encounter unexpected conditions, they tend to do one of two things:

  1. Fail catastrophically and dump sensitive info everywhere
  2. Fail open and grant access to literally everyone

Neither is ideal, folks.

Real-World Translation: This is the “we never tested what happens when the database is down” vulnerability. It’s the authentication bypass that only triggers on the 3rd Tuesday of months with a full moon when API rate limits are exceeded.


The Ones Who Fell: Down But Not Out 📉

🔻 A04: Cryptographic Failures (Was #2)

Dropped 2 spots but still critically important. You still can’t store passwords in plaintext, Karen.

🔻 A05: Injection (Was #3)

Dropped 2 spots but remains one of the most exploitable vulnerabilities. SQL injection in 2025 hits different—mostly because it’s still working and we should all be ashamed.

-- This meme brought to you by devs who learned about prepared statements
-- but decided "sanitization" meant checking for the word "union"
SELECT * FROM users WHERE username = '" + userInput + "';
-- Narrator: The userInput was not sanitized

🔻 A06: Insecure Design (Was #4)

Down 2 spots because companies are finally doing threat modeling. Progress? Progress.


The Consolidation: When Two Become One 💑

SSRF Gets Absorbed into Broken Access Control

The Merger: A10:2021 Server-Side Request Forgery is now just part of A01:2025 Broken Access Control.

The Logic: OWASP realized that SSRF is fundamentally an access control problem. When your server can be tricked into making requests it shouldn’t (like hitting http://169.254.169.254/latest/meta-data/), that’s broken access control with extra steps.

Before: “Our server can’t be SSRF’d!” After: “Wait, why is our server requesting the AWS metadata endpoint?” Also After: AWS credentials have left the chat

# Classic SSRF with access control vibes
url = request.get('url')  # User provides: http://localhost:6379/
response = requests.get(url)  # Your Redis: "why are you talking to me like this"
return response.content  # Attacker: *dumps internal data*

The Unchanged: Old Reliables 🎖️

👑 A01: Broken Access Control – Still King

4 years running at #1, affecting 3.73% of applications with 40 different CWEs. This is the GOAT of vulnerabilities.

Why It’s Still #1: Because developers are still checking:

if (user.id == requestedUserId) {
    // Show user data
}
// Attacker: *changes requestedUserId in URL*
// Also Attacker: "Why thank you for this admin account"

The Eternal Problem: Every. Single. Endpoint. Needs. Authorization. Checks. And devs keep forgetting this on endpoint #473.

A07: Authentication Failures – The Name Change

Formerly “Identification and Authentication Failures” because OWASP realized nobody could remember that mouthful. It’s still the same problems:

  • Weak passwords (still allowing “Password123!”)
  • Missing MFA (your startup’s “we’ll add it later” feature)
  • Session fixation (like 1998 called and wants its vuln back)
  • Credential stuffing (because password reuse is forever)

A08 & A09: The Steady Eddies

A08: Software and Data Integrity Failures and A09: Logging & Alerting Failures barely moved, but they’re still critical. One handles “is this code/data actually legit?” and the other is “did anyone notice we got breached six months ago?”


What This Means for Pentesters 🎯

The Testing Checklist Just Got Updated:

Start Prioritizing:

  1. 🎯 Supply chain recon is now mandatory—map those dependencies, check SBOMs, look for suspicious packages
  2. 🚨 Error handling testing needs to be systematic—what happens when you break things on purpose?
  3. ⚙️ Configuration reviews moved up the priority list—that cloud infrastructure won’t secure itself
  4. 🔐 Access control testing remains #1—IDOR hunting is still peak pentest energy

New Attack Surfaces:

  • Build pipelines and CI/CD systems
  • Package registries and artifact repos
  • Error handling in API endpoints
  • Exception flows in authentication mechanisms
  • Configuration management systems

Pro Pentester Move:

# The 2025 supply chain recon starter pack
sbom-tool generate -b . -ps YourApp
syft packages dir:. -o json | jq
grype dir:. --only-fixed
# Check for typosquatting
# Audit build dependencies
# Check for compromised maintainers
# Review your SCA tool's findings

What This Means for Developers 👨‍💻

The OWASP Top 10:2025 Developer Survival Guide:

Priority #1: Lock Down Access Control (Still!)

# Do this
if not user.has_permission(resource, 'read'):
    return 403
    
# Not this
if user.is_logged_in():  # 💀 This is not enough
    return resource

Priority #2: Audit Your Supply Chain

// Your package.json is a CVE buffet
{
  "dependencies": {
    "some-random-pkg": "^1.0.0",  // 2 dependencies
    "another-pkg": "^2.1.0"       // Depends on 47 packages
  }
  // Actual dependency count: 2,847 packages
  // Packages you've heard of: 2
  // Packages maintained by unpaid devs: All of them
}

Priority #3: Configuration Management

  • Use infrastructure as code (no more ClickOps)
  • Scan your configs with tools like Checkov, tfsec, or Prowler
  • Implement policy as code
  • Actually review those Terraform plans before applying

Priority #4: Fail Securely

// Good: Fail closed
func authenticate(user, pass string) error {
    result, err := db.CheckCredentials(user, pass)
    if err != nil {
        return ErrAuthenticationFailed  // 👍 Deny by default
    }
    return result
}

// Bad: Fail open  
func authenticate(user, pass string) error {
    result, err := db.CheckCredentials(user, pass)
    if err != nil {
        log.Println("DB error, granting access anyway")  // 💀
        return nil  // 🚨 Just let everyone in, what could go wrong?
    }
    return result
}

The Meta: How OWASP Built This List 🔬

The Data:

  • 📊 Over 2.8 million applications analyzed
  • 🔍 175,000+ CVE records reviewed
  • 🧬 589 CWEs mapped across 248 categories
  • 🏢 Multiple organizations contributed data (anonymously)

The Method:

  • 8 categories from hard data
  • 2 categories from community survey (because practitioners see things testing doesn’t catch yet)
  • Focus on root causes over symptoms
  • Prevalence over frequency (what % of apps are affected vs. how many times it happens)

The Timeline:

  • Release Candidate: November 6, 2025
  • Feedback window: Until November 20, 2025 (that’s TODAY if you’re reading this on publish day!)
  • Final release: Expected early 2026

The Hot Takes Section 🌶️

Take #1: The Supply Chain Promotion Makes Sense

The jump from “old libraries bad” to “your entire build process is suspect” reflects reality. Modern attacks target the supply chain because it’s effective. One compromised package = thousands of infected downstream apps. This category needed the upgrade.

Take #2: Error Handling Deserved Its Own Spot

Exception handling is where code meets reality, and reality is messy. Devs write happy path code and treat error handling as an afterthought. This category forces teams to think about “what happens when things break?”

Take #3: Misconfiguration at #2 is a Wake-Up Call

The cloud made configuration more important and more complex. Infrastructure as code means your misconfigurations are now version-controlled, repeatable, and deployed to production automatically. What a time to be alive.

Take #4: Injection at #5 is a Tragedy

SQL injection should be #47 by now. We have prepared statements! We have ORMs! And yet here we are, in 2025, with Bobby Tables still dropping databases. The fact it’s only at #5 isn’t because it’s less dangerous—it’s because we’re finally getting better at preventing it. Slightly.


Action Items for Your Team 🎬

This Week:

  • [ ] Review the OWASP Top 10:2025 RC
  • [ ] Assess your current security posture against the new list
  • [ ] Update your threat models with the new categories
  • [ ] Add supply chain security to your pentest scope

This Month:

  • [ ] Implement SBOM generation in your build pipeline
  • [ ] Audit error handling in critical authentication flows
  • [ ] Review cloud infrastructure configurations
  • [ ] Update your security training materials

This Quarter:

  • [ ] Integrate software composition analysis (SCA) tools
  • [ ] Establish supply chain security policies
  • [ ] Implement secure-by-default error handling patterns
  • [ ] Red team your error handling with chaos engineering

The Bottom Line 🎯

The OWASP Top 10:2025 reflects an uncomfortable truth: security is getting harder, not easier. Our attack surface expanded from “the code we write” to “the code we write + all the code we import + the tools that build it + the infrastructure that runs it.”

But here’s the thing—having the updated list means we know what to focus on. Broken access control is still king? Fix your authz. Supply chain is a risk? Audit those dependencies. Misconfiguration jumped to #2? Time to treat infrastructure as the code it literally is.

The list isn’t here to make us feel bad (though it does). It’s here to make us better.


Resources & Further Reading 📚


Closing Meme

Me in 2021: We just need to update our dependencies and we're good
Me in 2025: *auditing the political leanings of every npm package 
            maintainer*
            *checking if our build server has trust issues*
            *wondering if our CI/CD pipeline is a sleeper agent*

The supply chain: 🤷‍♂️ Always has been

Stay paranoid, stay patched, and may your attack surface be ever shrinking. 🛡️

Got thoughts on the new OWASP Top 10? Disagree with my takes? Found a typo? Drop a comment or @ me. Let’s argue about web security like the professionals we pretend to be.


Tags: #OWASP #WebSecurity #AppSec #PenetrationTesting #Top10 #SupplyChainSecurity #SecurityMisconfiguration #BrokenAccessControl #2025

Categories: