Name and explain the OWASP Top 10 web application risks, with a plain-English example and fix for each.
Why it matters
The OWASP Top 10 is a list of the most critical security risks to web applications, published by the Open Worldwide Application Security Project, a non-profit community. It is built from data contributed by security firms and from a community survey. Developers use it as a checklist, auditors cite it, job interviews ask about it, and certification exams expect you to know it. It is an awareness document, not a complete standard, but it is the best map of where web apps actually break.
The current edition is the OWASP Top 10:2025. Read the official pages for full details and examples at owasp.org/Top10. Checked on 2026-10-23.
The 2025 list in plain English
A01 Broken Access Control
The app lets users do things they should not. Example: changing /invoices/1001 to /invoices/1002 shows someone else's invoice (this is called an insecure direct object reference, or IDOR). Fix: check ownership and role on the server for every request; deny by default.
A02 Security Misconfiguration
Unsafe settings: default admin passwords, debug mode on in production, directory listings, verbose error pages, open cloud storage buckets. Fix: hardened, repeatable configuration, removing unused features, and automated checks.
A03 Software Supply Chain Failures
Your app is only as safe as the code and tools it depends on. Examples: an outdated library with a known vulnerability, a malicious package published under a look-alike name, a compromised build pipeline. Fix: keep an inventory of dependencies, update them, pin versions, use lockfiles and trusted registries, and protect your CI/CD system.
A04 Cryptographic Failures
Sensitive data is not protected properly: passwords stored with MD5, data sent over plain HTTP, hard-coded keys, homemade encryption. Fix: TLS everywhere, slow salted password hashing (bcrypt, scrypt, Argon2 or PBKDF2), well-known libraries, and proper key management (lesson 3.3).
A05 Injection
Untrusted input is treated as code. The classic example is SQL injection:
# Vulnerable: the input becomes part of the SQL text
cur.execute("SELECT * FROM users WHERE email = '" + email + "'")
# Safe: a parameterised query keeps data and code separate
cur.execute("SELECT * FROM users WHERE email = ?", (email,))
If email is ' OR '1'='1, the vulnerable version returns every user. Cross-site scripting (XSS) is injection into HTML and JavaScript; you will fix one in the next lesson. Fix: parameterised queries, safe APIs, output encoding, input validation.
A06 Insecure Design
The flaw is in the design itself, not a coding slip. Example: a password reset that asks "what is your favourite colour?", or a checkout with no limit on how many gift cards can be tried. Fix: threat modeling (previous lesson), secure design patterns, and abuse cases written next to user stories.
A07 Authentication Failures
Weaknesses in proving who someone is: no protection against password guessing, allowing known-breached passwords, session IDs that do not expire or are not renewed after login. Fix: MFA, rate limiting, checks against breached-password lists, and secure session handling.
A08 Software or Data Integrity Failures
The app trusts code or data without checking it has not been tampered with. Examples: auto-updates downloaded without signature checks, or deserialising untrusted objects that can run code. Fix: verify signatures and checksums, and do not deserialise untrusted data into objects.
A09 Security Logging and Alerting Failures
Attacks happen and nobody notices: failed logins are not logged, logs are never reviewed, no alert fires. Many breaches are discovered months later by outsiders. Fix: log security-relevant events (logins, access-control failures, admin actions) without logging secrets, centralise the logs, and alert on suspicious patterns.
A10 Mishandling of Exceptional Conditions
The app behaves unsafely when something unexpected happens: an error skips a permission check ("fail open"), a crash leaks a stack trace with internal details, or an unhandled edge case leaves data half-written. Fix: fail closed (deny when in doubt), handle errors consistently, show generic error messages, and test edge cases.
How the list changed
Compared with the 2021 edition, the 2025 list moves Security Misconfiguration up to second place, widens "Vulnerable and Outdated Components" into Software Supply Chain Failures, folds server-side request forgery into Broken Access Control, and adds Mishandling of Exceptional Conditions as a new category. Many tutorials and exam materials still use the 2021 names, so it is worth recognising both.
Worked example: mapping bugs to categories
A pentest report lists five findings for an online shop. Mapping them:
| Finding | Category |
|---|---|
Changing orderId in the URL shows other customers' orders | A01 Broken Access Control |
The admin panel still accepts admin / admin | A02 Security Misconfiguration (and A07) |
| A search box returns a database error when given a single quote | A05 Injection |
| The site uses a JavaScript library version with a published exploit | A03 Software Supply Chain Failures |
| 10,000 failed logins overnight produced no alert | A09 Security Logging and Alerting Failures |
Mapping findings this way helps teams spot patterns: three access-control bugs in one quarter suggest a missing shared authorization check, not three unrelated mistakes.
Common mistakes
- Treating the Top 10 as complete. It covers the most common risks, not all of them. For a fuller checklist, OWASP publishes the Application Security Verification Standard (ASVS).
- Trusting the client. Hidden form fields, disabled buttons and JavaScript checks are conveniences. Every rule must be enforced on the server.
- Fixing symptoms. Blocking the word
ORin input does not fix SQL injection; parameterised queries do.
Quick recap
- The OWASP Top 10 is the standard awareness list of web app risks; the current edition is 2025.
- Access control, misconfiguration, supply chain, cryptography and injection lead the list.
- Most fixes come down to a few habits: enforce rules on the server, keep data separate from code, use proven libraries, keep dependencies current, log and alert, and fail closed.