What is the OWASP Web Application Top 10?

The OWASP Top 10 is the most widely recognized awareness document for web application security. The 2025 edition reflects the latest threat landscape, introducing new categories such as Software Supply Chain Failures and Mishandling of Exceptional Conditions.

1️⃣ A01 - Broken Access Control

Critical

Overview

Access control enforces policy such that users cannot act outside of their intended permissions. Failures typically lead to unauthorized information disclosure, modification, or destruction of data, or performing a business function outside the user's limits.

Risk

Attackers can exploit access control flaws to access other users' accounts, view sensitive files, modify other users' data, or change access rights.

Vulnerable Code Example

Python ❌ Bad
# User ID taken directly from request without authorization check
@app.route('/api/user/<user_id>/profile')
def get_profile(user_id):
    user = db.get_user(user_id)  # No ownership check!
    return jsonify(user.to_dict())

Secure Code Example

Python ✅ Good
@app.route('/api/user/<user_id>/profile')
@login_required
def get_profile(user_id):
    # Verify the requesting user owns this resource
    if current_user.id != user_id and not current_user.is_admin:
        abort(403)

    user = db.get_user(user_id)
    if not user:
        abort(404)
    return jsonify(user.to_dict())

Mitigation Checklist

2️⃣ A02 - Security Misconfiguration

High

Overview

Security misconfiguration occurs when security settings are defined, implemented, or maintained incorrectly. This includes missing security hardening, unnecessary features enabled, default accounts with unchanged passwords, overly verbose error messages, and misconfigured HTTP security headers.

Risk

Misconfigured servers, frameworks, or cloud services can expose sensitive data, enable unauthorized access, or provide attackers with information to plan further attacks.

Vulnerable Code Example

Python ❌ Bad
# Debug mode enabled in production, verbose errors exposed
app = Flask(__name__)
app.config['DEBUG'] = True  # Exposes stack traces!
app.config['SECRET_KEY'] = 'default-secret'  # Default key!

Secure Code Example

Python ✅ Good
import os

app = Flask(__name__)
app.config['DEBUG'] = False
app.config['SECRET_KEY'] = os.environ['SECRET_KEY']

@app.after_request
def set_security_headers(response):
    response.headers['X-Content-Type-Options'] = 'nosniff'
    response.headers['X-Frame-Options'] = 'DENY'
    response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
    response.headers['Content-Security-Policy'] = "default-src 'self'"
    return response

Mitigation Checklist

3️⃣ A03 - Software Supply Chain Failures

High

Overview

New in 2025. Focuses on risks related to third-party components, dependencies, and CI/CD pipelines. Attackers target the software supply chain by compromising packages, injecting malicious code into open-source libraries, or exploiting build pipeline vulnerabilities.

Risk

A single compromised dependency can affect thousands of applications. Supply chain attacks can lead to data theft, backdoor installation, or complete system compromise with minimal detection.

Vulnerable Code Example

JavaScript ❌ Bad
// package.json with unpinned dependencies
{
  "dependencies": {
    "express": "*",           // Any version!
    "lodash": "^4.0.0",       // Wide range
    "unknown-pkg": "^1.0.0"   // Unvetted package
  }
}

Secure Code Example

JavaScript ✅ Good
// package.json with pinned versions + lockfile + audit
{
  "dependencies": {
    "express": "4.21.2",
    "lodash": "4.17.21"
  },
  "scripts": {
    "preinstall": "npx npm-audit-resolver",
    "integrity-check": "npm audit signatures"
  }
}
// Also: use package-lock.json, enable Dependabot/Renovate,
// generate SBOM, verify package provenance

Mitigation Checklist

4️⃣ A04 - Cryptographic Failures

High

Overview

Failures related to cryptography that often lead to exposure of sensitive data. This includes using deprecated algorithms, weak key generation, missing encryption for data in transit or at rest, and improper certificate validation.

Risk

Weak or missing encryption can expose passwords, credit card numbers, health records, personal information, and business secrets, potentially leading to regulatory violations (GDPR, PCI DSS).

Vulnerable Code Example

Python ❌ Bad
import hashlib

# Storing passwords with weak hashing
def store_password(password: str) -> str:
    return hashlib.md5(password.encode()).hexdigest()  # MD5 is broken!

Secure Code Example

Python ✅ Good
import bcrypt

def store_password(password: str) -> bytes:
    # Use bcrypt with automatic salting
    salt = bcrypt.gensalt(rounds=12)
    return bcrypt.hashpw(password.encode(), salt)

def verify_password(password: str, hashed: bytes) -> bool:
    return bcrypt.checkpw(password.encode(), hashed)

Mitigation Checklist

5️⃣ A05 - Injection

Critical

Overview

Injection flaws occur when untrusted data is sent to an interpreter as part of a command or query. SQL injection, NoSQL injection, OS command injection, and Cross-Site Scripting (XSS) are the most common forms. Hostile data can trick the interpreter into executing unintended commands.

Risk

Injection can result in data loss, corruption, unauthorized access, complete host takeover, or denial of service. SQL injection alone remains one of the most dangerous and prevalent attack vectors.

Vulnerable Code Example

Python ❌ Bad
# SQL injection via string concatenation
def get_user(username: str):
    query = f"SELECT * FROM users WHERE name = '{username}'"
    return db.execute(query)  # username = "' OR '1'='1"

Secure Code Example

Python ✅ Good
# Parameterized queries prevent SQL injection
def get_user(username: str):
    query = "SELECT * FROM users WHERE name = %s"
    return db.execute(query, (username,))

# For XSS prevention, escape output
from markupsafe import escape

def render_comment(comment: str) -> str:
    return f"<p>{escape(comment)}</p>"

Mitigation Checklist

6️⃣ A06 - Insecure Design

High

Overview

Insecure design refers to risks related to design and architectural flaws. It calls for the use of threat modeling, secure design patterns, and reference architectures. An insecure design cannot be fixed by a perfect implementation; the security controls needed were never created to defend against specific attacks.

Risk

Design flaws can lead to business logic vulnerabilities that are difficult to detect with automated tools. Missing rate limits on sensitive operations, lack of multi-factor authentication for critical actions, or insufficient fraud detection are all design-level failures.

Vulnerable Code Example

Python ❌ Bad
# Password reset with no rate limit or verification
@app.route('/reset-password', methods=['POST'])
def reset_password():
    email = request.form['email']
    new_pass = request.form['new_password']
    user = db.find_by_email(email)
    user.password = hash_password(new_pass)  # No token verification!
    db.save(user)

Secure Code Example

Python ✅ Good
from datetime import datetime, timedelta

@app.route('/reset-password', methods=['POST'])
@rate_limit("3/hour")
def reset_password():
    token = request.form['token']
    new_pass = request.form['new_password']

    # Verify time-limited, single-use token
    reset_req = db.find_reset_token(token)
    if not reset_req or reset_req.used or reset_req.expires < datetime.utcnow():
        abort(400, "Invalid or expired token")

    # Enforce password complexity
    if not meets_password_policy(new_pass):
        abort(400, "Password does not meet requirements")

    reset_req.user.password = hash_password(new_pass)
    reset_req.used = True
    db.save_all([reset_req.user, reset_req])

Mitigation Checklist

7️⃣ A07 - Authentication Failures

High

Overview

Confirmation of a user's identity, authentication, and session management is critical. Authentication failures occur when applications allow credential stuffing, brute force, weak passwords, or have flawed session management such as non-rotating session IDs after login.

Risk

Attackers can gain access to user accounts through automated credential stuffing, brute force, or session hijacking. Compromised accounts can lead to identity theft, fraud, and data breaches.

Vulnerable Code Example

Python ❌ Bad
# No brute force protection, weak session handling
@app.route('/login', methods=['POST'])
def login():
    user = db.find_by_email(request.form['email'])
    if user and user.password == request.form['password']:  # Plain comparison!
        session['user'] = user.id  # Session ID not rotated
        return redirect('/dashboard')

Secure Code Example

Python ✅ Good
from flask_limiter import Limiter

limiter = Limiter(app, default_limits=["100/hour"])

@app.route('/login', methods=['POST'])
@limiter.limit("5/minute")
def login():
    user = db.find_by_email(request.form['email'])
    if not user or not bcrypt.checkpw(
        request.form['password'].encode(), user.password_hash
    ):
        # Generic error to prevent user enumeration
        return "Invalid credentials", 401

    # Rotate session ID after authentication
    session.regenerate()
    session['user'] = user.id

    # Check for MFA requirement
    if user.mfa_enabled:
        return redirect('/mfa-verify')
    return redirect('/dashboard')

Mitigation Checklist

8️⃣ A08 - Software or Data Integrity Failures

High

Overview

Software and data integrity failures relate to code and infrastructure that do not protect against integrity violations. This includes insecure deserialization, using untrusted CDNs or plugins without integrity verification, and auto-update mechanisms without signed updates.

Risk

Insecure deserialization can lead to remote code execution. Loading scripts from untrusted CDNs without Subresource Integrity (SRI) can allow attackers to inject malicious code into your application.

Vulnerable Code Example

HTML ❌ Bad
<!-- Loading external scripts without integrity checks -->
<script src="https://cdn.example.com/lib.js"></script>

<!-- Insecure deserialization in Python -->
import pickle
data = pickle.loads(user_input)  # Arbitrary code execution!

Secure Code Example

HTML ✅ Good
<!-- Use Subresource Integrity (SRI) for external scripts -->
<script src="https://cdn.example.com/lib.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K..."
  crossorigin="anonymous"></script>

# Use safe deserialization in Python
import json
data = json.loads(user_input)  # Safe: only parses JSON data

Mitigation Checklist

9️⃣ A09 - Security Logging & Alerting Failures

Medium

Overview

Without sufficient logging, monitoring, and alerting, breaches cannot be detected in a timely manner. Insufficient logging, ineffective integration with incident response systems, and lack of real-time alerting allow attackers to further attack systems, maintain persistence, and tamper with or extract data.

Risk

Without proper logging, attackers can operate undetected for extended periods. Most breach studies show the average time to detect a breach exceeds 200 days, often discovered by external parties rather than internal monitoring.

Vulnerable Code Example

Python ❌ Bad
# No logging of security-relevant events
@app.route('/login', methods=['POST'])
def login():
    user = authenticate(request.form)
    if not user:
        return "Login failed", 401  # No record of failure
    return redirect('/dashboard')

Secure Code Example

Python ✅ Good
import logging
from datetime import datetime

security_log = logging.getLogger('security')

@app.route('/login', methods=['POST'])
def login():
    user = authenticate(request.form)
    if not user:
        security_log.warning(
            "LOGIN_FAILED | ip=%s | email=%s | time=%s",
            request.remote_addr,
            request.form.get('email', 'unknown'),
            datetime.utcnow().isoformat(),
        )
        check_brute_force(request.remote_addr)
        return "Invalid credentials", 401

    security_log.info(
        "LOGIN_SUCCESS | user_id=%s | ip=%s",
        user.id, request.remote_addr,
    )
    return redirect('/dashboard')

Mitigation Checklist

🔟 A10 - Mishandling of Exceptional Conditions

Medium

Overview

New in 2025. Applications that improperly handle errors, exceptions, and edge cases can expose sensitive information, enter inconsistent states, or create exploitable conditions. This includes verbose error messages in production, uncaught exceptions that bypass security controls, and race conditions.

Risk

Improper error handling can expose stack traces, database details, or internal paths. Race conditions in security checks can allow time-of-check-to-time-of-use (TOCTOU) attacks, bypassing authorization or payment validation.

Vulnerable Code Example

Python ❌ Bad
# Exposing internal details in error messages
@app.route('/api/data')
def get_data():
    try:
        result = db.query(request.args['q'])
        return jsonify(result)
    except Exception as e:
        return jsonify({"error": str(e)}), 500  # Leaks DB details!

Secure Code Example

Python ✅ Good
import uuid, logging

logger = logging.getLogger(__name__)

@app.errorhandler(Exception)
def handle_exception(e):
    error_id = str(uuid.uuid4())
    logger.error("Unhandled exception [%s]: %s", error_id, e, exc_info=True)

    # Return generic error with reference ID for support
    return jsonify({
        "error": "An internal error occurred",
        "reference": error_id,
    }), 500

@app.route('/api/data')
def get_data():
    q = request.args.get('q')
    if not q or not is_valid_query(q):
        return jsonify({"error": "Invalid query parameter"}), 400

    result = db.query(q)
    return jsonify(result)

Mitigation Checklist

📊 Summary Table

ID Vulnerability Severity Key Mitigation
A01Broken Access ControlCriticalServer-side access checks, deny by default, record ownership
A02Security MisconfigurationHighHardening process, security headers, disable defaults
A03Software Supply Chain FailuresHighPinned dependencies, SBOM, dependency scanning
A04Cryptographic FailuresHighStrong algorithms, TLS 1.2+, key management
A05InjectionCriticalParameterized queries, output encoding, input validation
A06Insecure DesignHighThreat modeling, secure patterns, abuse case testing
A07Authentication FailuresHighMFA, brute force protection, session rotation
A08Software or Data Integrity FailuresHighSRI, signed updates, safe deserialization
A09Security Logging & Alerting FailuresMediumCentralized logging, real-time alerts, incident response
A10Mishandling of Exceptional ConditionsMediumGlobal error handler, generic messages, TOCTOU prevention