OWASP Top 10 Explained: The Most Critical Web Application Risks
OWASP Top 10 Explained: The Most Critical Web Application Risks
The OWASP Top 10 is the definitive list of web application security risks. Understand each vulnerability, see real examples, and learn practical mitigation strategies.
What Is OWASP and the Top 10
The Open Worldwide Application Security Project (OWASP) is a nonprofit foundation dedicated to improving software security. Founded in 2001, OWASP produces freely available resources, tools, and documentation used by security professionals and developers worldwide.
The OWASP Top 10 is their flagship publication โ a consensus-driven list of the ten most critical security risks facing web applications. Updated periodically (most recently in 2021, with regular refreshes), it's based on data from hundreds of organizations covering hundreds of thousands of applications and millions of vulnerabilities.
Why the OWASP Top 10 matters for developers:
- It's the de facto industry standard for web application security awareness
- Many compliance frameworks (PCI DSS, SOC 2, ISO 27001) reference it directly
- Security auditors and penetration testers use it as a baseline checklist
- Understanding these ten risks prevents the majority of real-world application breaches
The Top 10 isn't exhaustive โ it doesn't cover every possible vulnerability. But fixing these ten categories eliminates the attack vectors used in the vast majority of web application breaches. Let's examine each one.
A01: Broken Access Control
Broken Access Control moved to the #1 position in the 2021 update โ it's the most common and most exploited web application vulnerability.
What it means: Access control enforces rules about what authenticated users are allowed to do. Broken access control means users can act outside their intended permissions โ accessing other users' data, modifying records they shouldn't, or performing admin functions without authorization.
Real-world examples:
- IDOR (Insecure Direct Object Reference): A URL like
/api/orders/12345returns order #12345. An attacker changes it to/api/orders/12346and accesses another customer's order. The server doesn't verify that the requesting user owns that order. - Privilege escalation: A normal user accesses
/admin/dashboardand gains admin functionality because the server only checks if the user is logged in โ not whether they have admin privileges. - Missing function-level access control: An API endpoint
/api/users/deleteexists for admins, but any authenticated user can call it because the access check is only on the frontend.
Prevention:
- Deny by default. Every resource should be inaccessible unless explicitly granted. Never rely on "security through obscurity" (hiding URLs).
- Server-side access checks. Never trust the client (frontend) to enforce access control. Every API endpoint must verify the requesting user's permissions.
- Use parameterized access. Instead of
/api/orders/:orderId, use the authenticated user's session to determine which orders they can access:/api/my-orders. - Implement RBAC (Role-Based Access Control) or ABAC (Attribute-Based Access Control) consistently across all endpoints.
- Log and alert on access control failures โ they may indicate an active attack.
A02: Cryptographic Failures
Previously called "Sensitive Data Exposure," this category focuses on failures related to cryptography โ or the lack thereof โ that lead to exposure of sensitive data.
What it means: Sensitive data (passwords, credit cards, personal information, health records) is inadequately protected through weak or missing encryption, poor key management, or outdated cryptographic protocols.
Common failures:
- Storing passwords in plaintext or with weak hashing. Using MD5 or SHA-1 for password hashing (instead of bcrypt, scrypt, or Argon2) allows attackers to crack passwords quickly if the database is breached.
- Transmitting data over HTTP. Any data sent without TLS is visible to network eavesdroppers.
- Using deprecated algorithms. DES, RC4, MD5, and SHA-1 are broken and should never be used for security purposes.
- Hardcoded encryption keys. Keys embedded in source code, configuration files, or Docker images.
- Insufficient key management. Using the same encryption key for years without rotation, or storing keys alongside the encrypted data.
Prevention:
- Use strong, modern algorithms: AES-256 for symmetric encryption, RSA-2048+ or Ed25519 for asymmetric, Argon2id for password hashing
- Enforce HTTPS everywhere with HSTS headers
- Never roll your own cryptography. Use well-established libraries: libsodium, OpenSSL, Web Crypto API
- Implement proper key management: rotate keys regularly, store them in secret management systems (HashiCorp Vault, AWS KMS), never in code
- Classify data by sensitivity and apply encryption appropriate to each classification
For password hashing specifically, see our guide on storing passwords securely with hashing.
A03: Injection
Injection attacks occur when untrusted data is sent to an interpreter as part of a command or query. The attacker's hostile data tricks the interpreter into executing unintended commands or accessing data without authorization.
Types of injection:
- SQL Injection: Malicious SQL code inserted into database queries
- Cross-Site Scripting (XSS): Malicious JavaScript injected into web pages viewed by other users
- Command Injection: Operating system commands injected through the application
- LDAP Injection: Malicious LDAP queries targeting directory services
- NoSQL Injection: Attacks targeting NoSQL databases (MongoDB, etc.)
- Template Injection: Server-side or client-side template engines executing attacker-controlled input
Example โ SQL Injection:
A login form takes a username and runs the query:
SELECT * FROM users WHERE username = ' + input + '
An attacker enters: ' OR '1'='1
The resulting query: SELECT * FROM users WHERE username = '' OR '1'='1' โ which returns all users, bypassing authentication.
Prevention:
- Use parameterized queries (prepared statements) for all database operations. This is the single most important defense against SQL injection. Every modern database library supports them.
- Use ORM frameworks that automatically parameterize queries (Prisma, SQLAlchemy, Hibernate)
- Validate and sanitize all input โ but never rely on sanitization alone as your primary defense
- Implement Content Security Policy (CSP) headers to mitigate XSS
- Use context-aware output encoding when rendering user data in HTML, JavaScript, CSS, or URLs
For detailed SQL injection prevention, see our dedicated guide: SQL Injection Prevention.
A04: Insecure Design
New in the 2021 Top 10, Insecure Design addresses flaws in the architecture and design of an application โ not implementation bugs. Even perfectly coded applications can be insecure if the underlying design is flawed.
What it means: The application's design doesn't account for security requirements. No amount of good coding can fix a fundamentally insecure design.
Examples:
- Missing rate limiting. A password reset endpoint allows unlimited attempts, enabling brute-force attacks on reset codes. The code is correct โ the design failed to consider abuse.
- Security questions as authentication. "What is your mother's maiden name?" is answerable from public records. The implementation is fine; the design choice of using security questions is the flaw.
- Excessive data exposure. An API returns the full user object (including password hash, internal IDs, and permissions) when the client only needs the display name. The API works correctly โ the design exposes more data than necessary.
- No transaction limits. A financial application allows unlimited transfer amounts without step-up authentication. The transfer code works perfectly โ the design failed to consider fraud.
Prevention:
- Threat modeling early in the design phase โ identify assets, threat actors, attack surfaces, and mitigations before writing code
- Design reviews with security-focused architects
- Apply the Principle of Least Privilege at the design level โ every component should have only the minimum access it needs
- Implement defense in depth โ don't rely on a single security control
- Use reference architectures with proven security patterns (OWASP ASVS provides a comprehensive checklist)
A05: Security Misconfiguration
Security misconfiguration is the most common finding in penetration tests. It's not about code bugs โ it's about improper configuration of servers, frameworks, libraries, databases, cloud services, and applications.
Common misconfigurations:
- Default credentials left unchanged โ database servers, admin panels, cloud dashboards
- Unnecessary features enabled โ directory listing, debug mode, sample applications, unused API endpoints
- Missing security headers โ Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security
- Overly permissive CORS โ
Access-Control-Allow-Origin: *on sensitive APIs - Cloud storage publicly accessible โ S3 buckets, Azure Blob containers, GCS buckets open to the internet
- Verbose error messages โ stack traces, database errors, and internal information returned to users
- Outdated software โ unpatched servers, frameworks, and libraries with known vulnerabilities
Prevention:
- Automated configuration scanning โ use tools like ScoutSuite, Prowler (cloud), or OWASP ZAP (web apps)
- Infrastructure as Code with security-hardened templates โ don't configure servers manually
- Minimal platform โ remove unused features, frameworks, ports, and services
- Security headers on all responses โ use securityheaders.com to verify
- Separate environments โ development settings should never reach production (no debug mode, verbose errors, or sample data)
A06: Vulnerable and Outdated Components
Modern applications are built on hundreds of third-party libraries and frameworks. Each is a potential vulnerability if outdated.
The scale of the problem:
- The average Node.js application has 700+ transitive dependencies
- A single vulnerable dependency (like Log4Shell in Log4j) can compromise millions of applications
- Known vulnerabilities in popular libraries are actively scanned for by attackers โ automated tools scan the internet for applications using vulnerable versions
Prevention:
- Maintain a Software Bill of Materials (SBOM) โ know every dependency in your application
- Automate dependency scanning with tools like Dependabot, Snyk, Renovate, or npm audit
- Pin dependency versions and update deliberately (don't use "latest" in production)
- Remove unused dependencies โ every dependency is an attack surface
- Subscribe to security advisories for your critical dependencies (GitHub Security Advisories, CVE databases)
- Have a patching process โ when a critical vulnerability is announced, how quickly can you update and deploy?
A07: Identification and Authentication Failures
This category covers weaknesses in the authentication and session management mechanisms โ the code that verifies "who are you?" and maintains that identity across requests.
Common failures:
- Permitting weak passwords โ no minimum length, no complexity requirements
- Missing brute-force protection โ no rate limiting or account lockout on login endpoints
- Insecure password storage โ plaintext, MD5, SHA-1 without salt
- Missing or broken multi-factor authentication (MFA)
- Session IDs in URLs โ exposed in browser history, logs, and referrer headers
- Sessions that don't expire โ tokens valid indefinitely
- Credential stuffing vulnerability โ no detection of automated login attempts using breached credentials
Prevention:
- Enforce strong password policies โ minimum 12 characters, check against known breached passwords
- Implement rate limiting on authentication endpoints
- Use secure password hashing โ Argon2id, bcrypt, or scrypt with appropriate cost factors
- Require MFA for sensitive operations and offer it for all accounts
- Use secure session management โ random session IDs, HttpOnly/Secure cookies, reasonable expiration
- Implement account lockout with progressive delays (not permanent lockout, which enables DoS)
Tools like our password generator and strength checker help users create credentials that resist these attacks.
A08โA10: Data Integrity, Logging, and SSRF
The final three risks in the Top 10:
A08: Software and Data Integrity Failures Failures related to code and infrastructure that don't protect against integrity violations. This includes:
- Insecure deserialization โ untrusted data is deserialized without validation, allowing remote code execution
- CI/CD pipeline compromise โ an attacker modifies the build pipeline to inject malicious code
- Auto-update without integrity verification โ software updates that don't verify signatures
Prevention: Verify digital signatures, use Subresource Integrity (SRI) for CDN resources, sign and verify CI/CD artifacts, and never deserialize untrusted data without validation.
A09: Security Logging and Monitoring Failures Without adequate logging, monitoring, and alerting, breaches go undetected. The average time to detect a data breach is still over 200 days (IBM Cost of a Data Breach Report).
Prevention: Log all authentication events (successes and failures), access control failures, input validation failures, and server-side errors. Implement alerting for anomalous patterns. Ensure logs are tamper-proof and retained according to your incident response plan.
A10: Server-Side Request Forgery (SSRF) SSRF occurs when a web application fetches a remote resource based on a user-supplied URL without validating it. An attacker can make the server request internal resources, scan internal networks, or access cloud metadata services.
Prevention: Validate and sanitize all user-supplied URLs. Use allowlists for permitted domains. Disable unnecessary URL schemes. Block requests to internal/private IP ranges. Use network segmentation to limit what the application server can access.
Getting Started with OWASP
The OWASP Top 10 is a starting point, not the finish line. Here's how to integrate it into your development practice:
For individual developers:
- Read through the full OWASP Top 10 documentation (owasp.org/Top10)
- Take the free OWASP Web Security Testing Guide as your reference for testing
- Use OWASP ZAP (free, open-source) to scan your applications
- Follow the OWASP Cheat Sheet Series for implementation guidance on specific topics
For development teams:
- Include OWASP Top 10 review in your code review checklist
- Run automated SAST (Static Application Security Testing) in your CI/CD pipeline
- Conduct periodic DAST (Dynamic Application Security Testing) scans
- Train all developers on secure coding practices annually
- Implement the OWASP Application Security Verification Standard (ASVS) for comprehensive coverage
Useful OWASP resources:
- OWASP Cheat Sheet Series โ practical implementation guides for every topic
- OWASP ASVS โ detailed security requirements for verification
- OWASP SAMM โ Software Assurance Maturity Model for organizations
- OWASP ZAP โ free security scanning tool
- OWASP Dependency-Check โ identifies known vulnerabilities in dependencies
The OWASP Top 10 distills decades of real-world breach data into ten actionable categories. Fixing broken access control, using proper cryptography, preventing injection, and addressing the other seven risks eliminates the attack vectors behind the vast majority of web application breaches. Whether you're a solo developer or part of an enterprise team, making these ten risks your security baseline is the highest-leverage investment in application security you can make.