The OWASP Top 10 is the software industry’s shared vocabulary for web application security. Whether you ship your first SaaS or review a vendor, it gives you a checklist of the risk categories behind the most real-world breaches. This guide explains every entry, what it means in practice, and how to defend against it.
What is OWASP
OWASP — the Open Worldwide Application Security Project — is a nonprofit, vendor-neutral community that produces free security resources. Its best-known output is the Top 10, a periodic ranking of the most common and impactful web application security risks, compiled from contributed data and community surveys. The list is an awareness document, not a compliance standard: it covers categories rather than specific vulnerabilities, and is a starting point, not an exhaustive catalog.
The current edition is the 2021 Top 10. Each entry includes an overview, real-world examples, a prevention section, and references to the relevant CWE weaknesses and deeper OWASP projects. Two entries changed significantly in 2021: Insecure Design and SSRF were added, reflecting community feedback about the rise of architectural flaws and cloud metadata attacks.
The Top 10 Risks Explained
A01: Broken Access Control
Access control failures let users act beyond their permissions: viewing another user’s records by changing an ID in the URL, calling an admin endpoint directly, or modifying objects without ownership checks. Because these flaws live in application logic, scanners often miss them.
How to fix it: Deny by default, enforce authorization on the server for every request, and centralize checks in shared middleware rather than sprinkling them through controllers. Add automated tests proving unprivileged users cannot reach protected endpoints.
A02: Cryptographic Failures
This category covers sensitive data exposed in transit or at rest: plaintext HTTP for login pages, weak or outdated algorithms, hardcoded keys, and unencrypted backups. It also includes failures to classify data — many teams encrypt nothing because they never decided what actually needs protection.
How to fix it: Use TLS everywhere, including internally. Classify data, encrypt sensitive fields at rest with vetted libraries, never invent your own cryptography, and never hardcode keys.
A03: Injection
Injection happens when untrusted input is interpreted as code — SQL statements, operating system commands, or LDAP queries. The classic case: a login form that concatenates user input into a query string.
How to fix it: Use parameterized queries (prepared statements) for database access, allowlists for anything that can’t be parameterized, and context-appropriate escaping. Give database accounts least-privilege permissions so that even a successful injection limits what an attacker can reach.
A04: Insecure Design
Insecure design is about architecture, not code: missing threat modeling, absent abuse-case analysis, and workflows that assume users behave. A booking system with no rate limits, or a reset flow that trusts a guessable security question, are flaws no hardening fully repairs.
How to fix it: Perform lightweight threat modeling during design, define security requirements alongside functional ones, and write abuse-case tests that simulate hostile usage before launch.
A05: Security Misconfiguration
Default credentials, verbose error pages that leak stack traces, directory listing enabled, unnecessary features switched on, missing security headers — misconfiguration is pervasive because modern stacks ship with insecure or bloated defaults.
How to fix it: Define a hardened baseline and deploy from repeatable, automated builds. Remove unused features and sample code, and review configurations on a schedule — our free website scanner checks several of these automatically.
A06: Vulnerable and Outdated Components
Most applications are mostly dependencies. When those libraries carry known vulnerabilities (published as CVEs) or reach end-of-life, every app that includes them inherits the exposure — even if your own code is perfect.
How to fix it: Maintain a software inventory (an SBOM is the modern approach), scan dependencies in CI with vulnerability databases, update promptly, and prefer maintained packages with a track record of security fixes.
A07: Identification and Authentication Failures
Weak or reused passwords, missing multi-factor authentication, weak session identifiers, and session fixation all fall here. Automated credential stuffing makes password-only authentication increasingly fragile.
How to fix it: Require or strongly encourage MFA (see our MFA setup guide), rate-limit login attempts, follow modern password guidance (prefer length over forced complexity, check new passwords against breach lists), and manage sessions with secure, rotated identifiers.
A08: Software and Data Integrity Failures
This category covers attacks before code reaches production: tampered updates, compromised CI/CD pipelines, unsigned artifacts, and insecure deserialization of untrusted data.
How to fix it: Sign artifacts and verify signatures at deployment, lock and review dependency versions, treat your CI/CD system as production infrastructure with its own access controls, and avoid deserializing untrusted input.
A09: Security Logging and Monitoring Failures
If no one records authentication failures, privilege changes, or unusual traffic patterns, an intrusion can run silently for months. Detection is a control, not an afterthought.
How to fix it: Log security-relevant events with enough context to investigate, ship logs to a central location that attackers can’t tamper with, define retention, and set up alerts — then rehearse responding to them.
A10: Server-Side Request Forgery (SSRF)
SSRF occurs when an application fetches a URL supplied by an attacker. Because the request originates from your trusted server, it can reach internal systems — including cloud metadata endpoints that expose credentials.
How to fix it: Allowlist legitimate destinations, block internal and loopback addresses, disable redirect following where possible, and segment your network so a successful SSRF finds nothing valuable.
Top 10 at a Glance
Fix the process, not just the bug: broken access control and injection are code-level; cryptographic failures, misconfiguration, and outdated components are operational; insecure design, integrity failures, and logging gaps are architectural. A mature program addresses all three layers.
How to Use OWASP in Development
The Top 10 is most valuable when it shapes your process rather than sitting in a training deck:
- Requirements phase: Walk through the ten categories and note which apply to your feature set. A file-sharing app and a payments page have very different top risks.
- Design reviews: Use A04 (Insecure Design) as a prompt for threat modeling and abuse cases before code is written.
- Implementation: Keep the OWASP Cheat Sheet Series handy for concrete, per-technology guidance — parameterized queries, CSP policies, session handling, and more.
- Code review: Maintain a short checklist per category so reviewers look for the same things consistently.
- Going deeper: When the Top 10 feels too coarse, graduate to the OWASP Application Security Verification Standard (ASVS), which provides detailed verification requirements by level.
Testing Your Application
No single tool catches every Top 10 category, which is why layered testing matters:
- Static analysis (SAST) in your IDE and CI pipeline catches injection, hardcoded secrets, and risky API calls early.
- Dependency scanning covers A06 by flagging vulnerable libraries before deployment.
- Dynamic testing (DAST) against a staging environment finds misconfigurations and runtime issues; open-source tools like OWASP ZAP are a practical starting point.
- Manual testing remains essential for logic flaws — broken access control and business-rule abuse are hard for scanners to model.
- External checks complement application testing — our free website scanner verifies TLS, headers, and email authentication from outside.
Conclusion
The OWASP Top 10 is a baseline, not a destination. Used well, it gives your team a shared language, a prioritization frame, and process hooks — from design reviews to CI checks — that catch classes of problems instead of individual bugs. Start with the categories your application is most exposed to, fix the systemic causes, and keep the list present in every stage of your workflow.