Python OWASP Top Ten — Core Concepts

What Is the OWASP Top Ten?

The Open Web Application Security Project publishes a ranked list of the most critical web application security risks, updated roughly every 3–4 years. The 2021 edition reflects data from hundreds of organizations covering over 500,000 applications. It’s the de facto standard for web security awareness and is referenced in PCI-DSS, SOC 2, and government security frameworks.

A01: Broken Access Control

The number-one risk. Your app checks whether a user is logged in, but doesn’t check whether they’re allowed to access that specific resource.

Python context: Django’s @login_required decorator verifies authentication but not authorization. You need @permission_required or object-level checks. In FastAPI, use dependency injection to verify the user’s role against the requested resource.

Common mistake: Filtering menu items in the UI but not enforcing on the API. An attacker bypasses the UI entirely by calling the API endpoint directly with modified IDs.

A02: Cryptographic Failures

Sensitive data exposed through weak or missing encryption. This includes storing passwords with MD5, transmitting data over HTTP, or using outdated TLS versions.

Python context: Django stores passwords with PBKDF2-SHA256 by default — but only if you use User.set_password(). Manually hashing with SHA-256 defeats the built-in protection. Flask doesn’t hash passwords by default; you need werkzeug.security.generate_password_hash() or bcrypt.

A03: Injection

Untrusted data sent to an interpreter as part of a command or query. SQL injection is the classic example, but it includes OS command injection, LDAP injection, and template injection.

Python context: Django ORM and SQLAlchemy parameterize queries automatically. The danger arises with raw SQL: cursor.execute(f"SELECT * FROM users WHERE id = {user_id}") is injectable; cursor.execute("SELECT * FROM users WHERE id = %s", [user_id]) is safe. Jinja2’s |safe filter and Django’s mark_safe() disable auto-escaping for HTML output — use them only with data you’ve sanitized yourself.

A04: Insecure Design

Security flaws baked into the architecture, not just the implementation. No amount of good code fixes a design that doesn’t include threat modeling.

Python context: An API that returns unlimited results without pagination enables denial-of-service. A password reset flow that answers security questions without rate limiting enables brute-force. These aren’t bugs — they’re design gaps.

Mitigation: Threat model during design. Ask: “What happens if an attacker controls this input?” for every data flow.

A05: Security Misconfiguration

Debug mode in production, default credentials, unnecessary features enabled, missing security headers.

Python context: Django’s DEBUG = True in production exposes stack traces, database queries, and settings. Flask’s app.debug = True enables the interactive debugger with code execution. FastAPI’s auto-generated /docs endpoint should be disabled or protected in production.

Checklist: Set DEBUG = False, configure ALLOWED_HOSTS, enable SECURE_SSL_REDIRECT, set SESSION_COOKIE_SECURE, add X-Content-Type-Options, X-Frame-Options, and Content Security Policy headers.

A06: Vulnerable and Outdated Components

Using libraries with known CVEs. The 2017 Equifax breach exploited a known Apache Struts vulnerability that had been patched months earlier.

Python context: Run pip audit or safety check regularly. Pin dependencies in requirements.txt and update them deliberately. Tools like Dependabot and Snyk monitor your pyproject.toml for newly disclosed vulnerabilities.

A07: Identification and Authentication Failures

Weak passwords, credential stuffing, missing multi-factor authentication, session fixation.

Python context: Django’s authentication framework includes password validators (minimum length, common password check, similarity to user attributes). Enable them. Use django-axes or similar for brute-force protection. In FastAPI, use JWT with short expiration times and refresh token rotation.

A08: Software and Data Integrity Failures

Trusting updates, CI/CD pipelines, or serialized data without verification. This includes insecure deserialization — Python’s pickle.loads() on untrusted data executes arbitrary code.

Python context: Never unpickle data from untrusted sources. Verify package integrity with hash checking (pip install --require-hashes). Sign deployment artifacts and verify signatures before execution.

A09: Security Logging and Monitoring Failures

If you can’t detect a breach, you can’t respond. The average time to detect a breach is 287 days (IBM 2021 report).

Python context: Log authentication events (successful and failed), authorization failures, input validation failures, and application errors. Use structured logging (structlog or python-json-logger). Send logs to a centralized system (ELK, Datadog, Sentry) where anomaly detection can spot patterns.

A10: Server-Side Request Forgery (SSRF)

The application fetches a URL supplied by the user without validating the destination. An attacker can probe internal networks, access cloud metadata endpoints (169.254.169.254), or reach internal services.

Python context: If your app fetches user-supplied URLs (webhooks, image imports, link previews), validate the hostname against an allowlist. Block private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, 169.254.x). Use network-level controls (firewall rules, VPC configuration) as defense-in-depth.

Common Misconception

“My framework handles security automatically.” Django, Flask, and FastAPI provide security features, but they’re opt-in or can be accidentally bypassed. Django auto-escapes templates — unless you use |safe. Django ORM prevents SQL injection — unless you use raw() or extra(). The framework provides the tools; the developer must use them correctly.

The one thing to remember: the OWASP Top Ten isn’t a penetration testing checklist — it’s a design checklist. Address these ten categories during development, not after deployment, and you’ll prevent the overwhelming majority of real-world web attacks.

pythonsecurityweb-development

See Also