Interactive Playground
Experiment with the vulnerable code and security rule below. Edit the code to see how the rule detects different vulnerability patterns.
pathfinder scan --ruleset python/PYTHON-DJANGO-SEC-072 --project .About This Rule
Understanding the vulnerability and how it is detected
This rule detects insecure deserialization vulnerabilities in Django applications where untrusted user input from HTTP request parameters flows into unsafe deserialization functions: pickle.loads(), yaml.load(), dill.loads(), shelve.open() with user-controlled keys, or similar functions that execute code during deserialization.
Python's pickle module, by design, executes arbitrary code during deserialization. YAML's yaml.load() with the default Loader executes Python constructors (!!python/object) during loading. These are not bugs -- they are features for legitimate internal use -- but they become critical vulnerabilities when applied to user-controlled data.
An attacker who can supply a crafted pickle or YAML payload can execute arbitrary Python code on the server during the deserialization call, with the same privileges as the Django process. This is equivalent in severity to eval() or exec() injection.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Direct Remote Code Execution via Pickle
Python's pickle module executes __reduce__ methods during deserialization. A crafted pickle payload can define a __reduce__ that calls os.system(), subprocess.Popen(), or any other function at deserialization time. This is one of the most well-known RCE vectors in Python web applications.
YAML Deserialization RCE via Python Tags
yaml.load() with the default or FullLoader can execute Python constructors using YAML tags like !!python/object/apply:os.system ['whoami']. An attacker who controls YAML input can execute arbitrary OS commands at load time. yaml.safe_load() restricts to standard YAML types only and is not vulnerable.
dill and shelve Deserialization
The dill library is a superset of pickle with even more serialization capabilities, making dill.loads() with user input equally dangerous. shelve.open() uses pickle internally, so opening shelve databases with user-controlled keys against user-provided data creates the same risk.
Persistent Backdoor Installation
Deserialization RCE can be used to install persistent backdoors: writing malicious code to application directories, modifying the codebase, adding admin accounts, or establishing reverse shell connections that persist after the initial attack.
How to Fix
Recommended remediation steps
- 1Replace pickle.loads(), dill.loads(), and similar calls with json.loads() for data exchange between systems.
- 2When YAML is required, always use yaml.safe_load() which restricts parsing to standard YAML types and does not execute Python constructors.
- 3Never deserialize data from HTTP requests using pickle, dill, or yaml.load() with any Loader that supports Python object construction.
- 4Store application state and user data in the database using Django's ORM, not as serialized Python objects.
- 5If pickle must be used for caching or internal IPC, sign the serialized data with HMAC and verify the signature before deserializing to prevent tampering.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
This rule performs inter-procedural taint analysis with global scope. Sources include calls("request.GET.get"), calls("request.POST.get"), calls("request.GET.__getitem__"), calls("request.POST.__getitem__"), calls("request.body"), and calls("request.read"). Sinks include calls("pickle.loads"), calls("pickle.load"), calls("dill.loads"), calls("dill.load"), calls("yaml.load"), calls("yaml.full_load"), and calls("yaml.unsafe_load") with tainted input tracked via .tracks(0). Sanitizers include calls("yaml.safe_load") and calls("json.loads") which parse data safely without code execution. The rule follows taint across file and module boundaries.
Compliance & Standards
Industry frameworks and regulations that require detection of this vulnerability
References
External resources and documentation
Similar Rules
Explore related security rules for Python
Frequently Asked Questions
Common questions about Django Insecure Deserialization of Request Data
New feature
Get these findings posted directly on your GitHub pull requests
The Django Insecure Deserialization of Request Data rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.