OWASP Top 10:2025 — A Security Map, Not a Memorization List
A practical guide to understanding the OWASP Top 10:2025 through root causes, realistic scenarios, category boundaries, and durable defenses.
Table of contents · 18 sections
When I first encountered the OWASP Top 10, I saw a tidy list of ten items. Naturally, I assumed the task was to memorize those ten headings.
A01 access control
A02 misconfiguration
A03 supply chain
...
I eventually realized that reciting the headings in order solves very little. When I intercept a request in Burp Suite, the real question is not “Which number was this?” It is: What does the system trust here, where is the control missing, and what is the actual impact?
This article treats the OWASP Top 10:2025 not as an exam syllabus, but as a way to examine web applications. My goal is not to memorize a few payloads for every category. It is to understand the root cause, the boundaries, the differences between related categories, and the durable defense.
Currency note: As of August 2026, OWASP Top 10:2025 is the current list for mainstream web applications. There is no separate main web application list called “OWASP Top 10:2026.” API, mobile, LLM, and smart-contract lists are separate projects and should not be confused with this one.
What is OWASP, and what is the Top 10 for?
OWASP—the Open Worldwide Application Security Project—is a global community that produces open standards, testing guides, checklists, laboratories, and tools for improving software security.
The Top 10 is its best-known resource, but it is not the entire ecosystem:
| Resource | How I use it |
|---|---|
| OWASP Top 10 | Risk awareness and shared vocabulary |
| ASVS | Actionable security requirements |
| WSTG | A systematic web security testing approach |
| Cheat Sheet Series | Implementation guidance for specific controls |
| Juice Shop / WebGoat | Legal, controlled practice |
The Top 10 is not a penetration-testing methodology, a vulnerability scanner, or a certificate that says, “I checked these, therefore the application is secure.” Each entry represents a broad risk family containing weaknesses with related root causes, not one individual vulnerability.
CWE → A class of weakness
CVE → A record of a concrete vulnerability in a specific product
OWASP → Groups many weaknesses into broad risk families
For example, CWE-89 describes the SQL Injection weakness class. A concrete SQL Injection vulnerability in a particular product may receive a CVE. OWASP A05 covers SQL, command, template, and many other forms of injection as a wider family.
The 2025 list combines data from real application testing with community analysis. That matters because automated tools can detect some technical weaknesses easily, while risks such as business-logic flaws and insecure design may appear smaller than they really are in data sets.
What changed in the 2025 list?
The current ranking is:
| Rank | Category | My short question |
|---|---|---|
| A01 | Broken Access Control | Is this actor allowed to perform this action? |
| A02 | Security Misconfiguration | Is the system configured securely? |
| A03 | Software Supply Chain Failures | Can I trust the components I bring in? |
| A04 | Cryptographic Failures | Are the data and keys protected correctly? |
| A05 | Injection | Can data become a command? |
| A06 | Insecure Design | Was the required control designed in from the start? |
| A07 | Authentication Failures | Is the actor really who they claim to be? |
| A08 | Software or Data Integrity Failures | Has the software or data been modified? |
| A09 | Security Logging and Alerting Failures | Can I see the attack and respond? |
| A10 | Mishandling of Exceptional Conditions | Does the system remain secure when things go wrong? |
Broken Access Control remains first. Security Misconfiguration moved to second. “Vulnerable and Outdated Components” expanded into Software Supply Chain Failures. SSRF moved under A01. Alerting received explicit emphasis in the logging category, and a new A10 was added for mishandling exceptional conditions.
A01:2025 — Broken Access Control
Authentication tells me who the user is. Access control determines which actions that user may perform on which resources.
Authentication → Who are you?
Authorization → Are you allowed to do this?
Confusing the two creates a dangerous shortcut: “The user is signed in, so the request is allowed.”
A classic IDOR/BOLA example:
GET /api/invoices/1001
My invoice opens. If changing the ID to 1002 returns another user’s invoice, the server checked that the object exists and that I have a session, but failed to check whether the object belongs to me.
Does the object exist? Yes
Is the user signed in? Yes
Does it belong to them? Not checked
Moving to another user’s data is horizontal privilege escalation. Moving from a regular user to administrator capabilities is vertical privilege escalation. Hiding an admin button in the frontend prevents neither. If the API endpoint has no server-side check, making a button invisible with CSS is not a security control.
This family can include IDOR, forced browsing, missing method authorization, role manipulation, some CORS failures, CSRF, and—in the 2025 list—SSRF. The access-control logic behind SSRF is that an attacker makes the server exercise its network privileges on the attacker’s behalf:
User → Server → 127.0.0.1 / internal-service / cloud metadata
Defenses include deny by default, centralized server-side policy, ownership checks for every object, tests by endpoint and HTTP method, short-lived tokens, correct logout behavior, and alerts for repeated authorization violations.
Being signed in does not give you the key to every door.
A02:2025 — Security Misconfiguration
I can make a system vulnerable without changing a single line of application code. Debug mode remains enabled, storage is public, the default password is unchanged, or an .env file lands in the web root. The code performs its job correctly; its surroundings are too permissive.
A modern application stack is not short:
CDN → Cloud → Load balancer → Reverse proxy → Container
→ Framework → Application → Database → Cache → Queue
Every layer introduces another configuration surface. Directory listing, stack traces in production, unnecessary ports, test endpoints, actuator panels, incorrect CORS, missing security headers, unnecessary HTTP methods, public buckets, default accounts, and insecure XML parsers can all belong to this family.
The defense is not “configure it once and forget it.” It requires repeatable hardening standards, Infrastructure as Code, separation between development, test, and production, least privilege, secret management, secure baselines, and configuration-drift detection. If a secure setting can drift over time, I must continuously verify it.
Secure code does not remain magically secure on misconfigured infrastructure.
A03:2025 — Software Supply Chain Failures
How much of a modern application did I actually write? Packages, base images, CI actions, SDKs, IDE extensions, and build tools bring an entire neighborhood of external code into my repository and build process.
The risk is not limited to an “old npm package.” Typosquatting, dependency confusion, compromised maintainer accounts, malicious updates, unsafe GitHub Actions, leaked CI/CD secrets, unsigned artifacts, backdoored base images, and unprotected artifact registries are all parts of the chain.
Transitive dependencies are particularly deceptive:
My application
└── Package A
└── Package B
└── Package C ← the problem is here
The risk does not disappear because I did not install Package C directly. Once it enters the running software, it enters my responsibility chain.
An SBOM—Software Bill of Materials—shows which components are present. Generating an SBOM and forgetting it in a directory does not provide security. A process must match inventory against CVEs, assign ownership, assess risk, and apply updates.
Lock files, version pinning, trusted registries, package and artifact signatures, SCA, SBOMs, minimal base images, least-privilege CI/CD, branch protection, and pinning critical actions to immutable commit hashes all contribute to the defense.
Application security is only as strong as every component I allow into the build, not merely the code I write.
A04:2025 — Cryptographic Failures
The first trap in cryptography is the sentence, “We use encryption.” Which algorithm and mode? Where is the key? Is the nonce reused? Is the certificate genuinely validated? How is the password stored? Cryptography may be present but used in the wrong place or with the wrong lifecycle.
I first separate three concepts:
Encoding → Changes format; provides no confidentiality
Encryption → Hides data with a key; an authorized party can recover it
Hashing → Produces a one-way digest
Base64 != encryption. A Base64-encoded password is not protected; it is merely represented in another form.
Passwords should not be stored as plaintext, MD5, SHA-1, or a fast unsalted SHA-256 digest. Password storage requires slow, salted schemes such as Argon2id, scrypt, bcrypt with an appropriate cost, or PBKDF2 with suitable parameters.
The risk family includes unencrypted sensitive data, weak algorithms, hard-coded keys, missing key rotation, incorrect certificate or hostname validation, predictable tokens, nonce/IV reuse, plaintext protocols, and TLS downgrade.
Defense begins with classifying data and not collecting sensitive data that is unnecessary. Standard current algorithms, CSPRNGs, authenticated encryption, KMS/HSM, key rotation, mandatory TLS, and correct certificate validation continue that defense.
Cryptography is not merely algorithm selection; it is the management of data, keys, randomness, and lifecycles.
A05:2025 — Injection
Injection has a shared root cause: user input that should remain data is interpreted by an interpreter as part of a command or query.
Unsafe SQL logic:
query = "SELECT * FROM users WHERE username = '" + username + "'"
The input becomes part of the query text. A parameterized approach separates data from query structure:
cursor.execute(
"SELECT * FROM users WHERE username = %s",
(username,)
)
The same idea applies to command injection. With os.system("nslookup " + user_input), I place input directly inside shell grammar. Where possible, I should remove the shell. If it is unavoidable, I should pass arguments separately, validate against an allowlist, and run the operation with least privilege.
SQL, OS shells, LDAP, NoSQL, XPath, and template engines are different interpreters. In XSS, content that should remain data is interpreted by the browser as executable code. Defenses depend on context but share a line: parameterized queries, context-aware output encoding, safe template engines, server-side validation, and structural separation of data from commands.
User data must not become part of the grammar of an executable language.
A06:2025 — Insecure Design
If a control exists but the code implements it incorrectly, that is an implementation bug. If nobody designed the control at all, that is a design flaw. They are not the same; in the second case, code review may have no single incorrect line to fix.
Examples include no transfer limit, a coupon reusable through concurrent requests, negative item quantities, no reauthentication for a critical action, tenant isolation never being designed, or a missing rate-limit requirement.
During threat modeling, I ask:
- What am I protecting?
- Who can attack it?
- Where is the trust boundary?
- Which components handle the data?
- What can go wrong?
- How should the system behave when a control fails?
A normal use case may say, “The user applies a coupon.” An abuse case asks, “What happens when the user applies the same coupon in one hundred concurrent requests?” If I never ask that during design, even immaculate code will not invent the missing business rule by itself.
Security requirements, threat models, abuse cases, business rules in the domain layer, quotas and rate limits, step-up authentication, atomic transactions, rollback, and negative tests are where the defense must begin.
If a security control is absent from the design, clean code does not create it retroactively.
A07:2025 — Authentication Failures
Authentication is not simply entering a username and password into a login form. Registration, login, MFA, session creation, password reset, remember-me behavior, token renewal, and logout are parts of the same identity lifecycle.
Credential stuffing automatically tests email:password pairs from other breaches against a target. A strong-password rule alone is therefore insufficient; breached-password screening, rate limiting, MFA, and anomaly detection are also needed.
In session fixation, an attacker determines the session ID the victim will use in advance. If the session ID is not regenerated after login, the attacker can take over that session. Rotating the session ID during login is a fundamental part of the fix.
The Secure, HttpOnly, and SameSite cookie flags matter, but they are not a magical trio that solves all session security. Predictable tokens, excessive lifetimes, failure to revoke on logout, unsafe reset flows, user enumeration, and MFA bypass remain relevant.
MFA, breached-password blocking, generic error messages, cryptographically secure random tokens, short lifetimes, reauthentication, session rotation after login, revocation after logout, and alerts for authentication events must work together.
Authentication is not a screen. It is an end-to-end managed lifecycle.
A08:2025 — Software or Data Integrity Failures
Integrity asks: “Could this software or data have been modified without authorization after leaving a trusted source?” Knowing the source’s name alone does not answer the question; verification does.
Accepting unsigned updates, not checking signatures, loading unsafe plugins, deploying unverified artifacts, trusting client-side state, and processing queue or cache data without validation can belong here.
Insecure deserialization is also important. If an application opens attacker-controlled serialized data as a trusted object, the result may include privilege changes, object injection, logic abuse, data manipulation, and—in some technologies—code execution.
I remember the boundary with A03 this way:
A03 → How can the dependency, build, and distribution ecosystem be compromised?
A08 → Do I genuinely verify the integrity of the software or data I receive?
Both can exist in the same incident. A malicious package is a supply-chain problem; a build system accepting an unsigned artifact is also an integrity problem.
Signed updates, hash and signature verification, provenance, immutable artifacts, trusted repositories, explicit data schemas, avoiding native deserialization, and failing closed when validation fails are foundational defenses.
“I know where it came from” and “I verified that it was not changed” are not the same statement.
A09:2025 — Security Logging and Alerting Failures
Logging answers, “What happened?” Alerting asks, “If this event is suspicious enough, who will act, when, and how?”
Successful and failed login, MFA failures, password resets, authorization denials, administrative actions, role changes, critical data access, financial transactions, rate limits, session revocation, configuration changes, and unexpected exceptions should be recorded meaningfully.
A log is not a dumping ground for everything. Plaintext passwords, access or session tokens, private keys, secrets, complete payment-card data, and unnecessary personal data must not be logged.
A useful security event includes a timestamp, event type, user or system identity, correlation ID, target resource, result, and risk level. Logs should be centralized, clocks synchronized, access restricted, and records protected from easy attacker modification.
Login attempts against many accounts from one IP, repeated admin-endpoint requests by a regular user, critical configuration changes, increasing 403/404 responses, an exception storm, or a stopped log pipeline can justify alerts. Each alert must connect to a real playbook and an accountable person.
I cannot analyze an event I did not record, and I cannot respond in time to an event that never raises an alert.
A10:2025 — Mishandling of Exceptional Conditions
This category is new in the 2025 list. An application may behave perfectly under normal conditions. What happens when the database disconnects midway, the disk fills, a parameter is missing, a timeout occurs, an external service returns a partial response, or two requests modify the same state concurrently?
OWASP focuses on failing to prevent an exceptional condition, detect it while it occurs, or respond safely afterward. Missing input validation, uncaught exceptions, incorrect return values, null dereferences, missing resource cleanup, sensitive stack traces, and failing open can all contribute.
A fail-open example:
Authorization service did not respond → allow the user in
A fail-closed approach:
Authorization could not be verified → stop the operation in a controlled way
Consider a money transfer:
- Deduct money from the sender.
- Add money to the recipient.
- Create the transaction record.
If the network fails during step two and the entire transaction is not rolled back, the state can become inconsistent. Likewise, if a database connection, lock, file handle, or memory is not released after an exception, an attacker may repeatedly trigger the error to exhaust resources.
A race condition is not merely “two very fast requests.” It is a state transition that was not designed to be atomic:
Is the coupon unused? Yes.
Apply the coupon.
Mark it as used.
If two requests pass the first check at the same time, the coupon may be applied twice.
Local exception handling, a global final safety net, controlled user messages, safe technical logs, alerts, atomic transactions, rollback, resource cleanup, timeouts, retry policy, circuit breakers, quotas, rate limits, state machines, invariants, and fault-injection tests are defensive tools for this category.
Real security means the system behaves in a controlled way even when the plan breaks.
How do I distinguish similar categories?
One incident may relate to more than one category. I look at the root cause, not the most visible symptom, when choosing an OWASP label.
| Categories that overlap | Distinguishing question |
|---|---|
| Authentication / Access Control | Was identity not verified, or was authorization not enforced? |
| Misconfiguration / Insecure Design | Was the control configured incorrectly, or never designed? |
| Supply Chain / Integrity | Was the chain compromised, or was the received artifact not verified? |
| Injection / Exceptional Conditions | Did data become a command, or was an unexpected state handled badly? |
An admin endpoint hidden in the frontend but open in the API is an access-control issue. If no mechanism to protect the endpoint was ever designed, insecure design may also be relevant. Production debug output is misconfiguration; an exception exposing a sensitive stack trace can also intersect with A10.
Category selection is not always a perfect box. The important thing is to state the root cause clearly in the report and never let the label replace the evidence.
A safe lab and study plan
I practice these topics in controlled laboratories rather than unauthorized live systems:
- OWASP Juice Shop
- OWASP WebGoat
- PortSwigger Web Security Academy
- DVWA
- crAPI
- My own local Docker lab
A ten-day plan can look like this:
- A01 — IDOR, role transitions, and forced browsing
- A02 — Debug settings, headers, default credentials, and cloud permissions
- A03 — Dependency trees, SCA, and SBOMs
- A04 — Hashing, TLS, token entropy, and key management
- A05 — SQLi, XSS, and command injection
- A06 — Threat models, abuse cases, and business limits
- A07 — Sessions, reset flows, MFA, and logout
- A08 — Signatures, provenance, and deserialization
- A09 — Event schemas, masking, correlation, and alerts
- A10 — Timeouts, rollback, fail closed, and fault injection
Instead of merely running a payload each day, I try to answer eight questions:
1. What asset is being protected?
2. Where is the trust boundary?
3. Which input does the attacker control?
4. Which control is missing or incorrect?
5. Why does the system trust this input?
6. What is the technical impact?
7. What is the business impact?
8. Which fix removes the root cause?
How do I report what I find?
“I found A01” is not a report. A good report enables another person to reproduce the problem, understand the impact, and fix the correct layer.
## Title
[Concrete impact] caused by [vulnerability class]
## Affected asset
- URL / endpoint / method
- Role and environment
## Preconditions
- Is authentication required?
- Which role is needed?
- Is user interaction required?
## Technical root cause
Where and why is the control missing?
## Reproduction steps
1. ...
2. ...
## Expected / actual behavior
What should the system do, and what did it do?
## Impact
- Confidentiality
- Integrity
- Availability
- Business impact
## Classification
- OWASP Top 10
- CWE
- CVSS
## Remediation
A recommendation that removes the root cause, not merely the symptom.
The OWASP category helps organize the report; it does not replace evidence, scope, or impact analysis.
Conclusion: Learn the reasoning, not the list
The weak study method looks like this:
Memorize ten headings
→ copy two payloads
→ run a scanner
→ assume the job is done
A stronger method is:
Identify the asset
→ find the trust boundary
→ trace user-controlled input
→ identify the missing control
→ explain the root cause
→ separate technical and business impact
→ design a durable defense
My short summary:
A01 The authorization boundary breaks.
A02 The system is configured incorrectly.
A03 The supply chain carries an untrusted component.
A04 Data or keys are protected incorrectly.
A05 Data becomes a command.
A06 A required control is missing from the design.
A07 The identity and session lifecycle breaks.
A08 Software or data integrity is not verified.
A09 The attack is unseen or generates no alert.
A10 An exceptional condition is not handled safely.
The OWASP Top 10 is not a payload list. It is a security reasoning model that teaches me to examine not just the screen that works, but the authorization boundary, configuration, build chain, data flow, design decisions, and behavior when failures occur.
Official resources
- OWASP Top 10:2025
- OWASP Top 10 project
- OWASP Application Security Verification Standard
- OWASP Web Security Testing Guide
- OWASP Cheat Sheet Series
Image credits
- The cover and A01–A10 technical illustrations were created locally for this article.
$ leave_reaction --one
What did this article leave with you?
Choose one reaction. You can change your choice later.
This choice is stored only in this browser. No personal data or reaction information is sent to a server.