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-081 --project .About This Rule
Understanding the vulnerability and how it is detected
This rule detects a specific Django password vulnerability pattern where request.POST.get('password', '') -- using an empty string as the default value -- flows into set_password() without an intervening check for empty/None values.
This pattern is subtly dangerous because it appears to handle the case where the password field is missing from the request. However, instead of rejecting the missing password as an error, it silently defaults to an empty string and creates an account accessible without any password.
The vulnerability manifests when a user omits the password field from a registration form, or when an API client sends a request without the password parameter. Rather than receiving an error, the user's account is created with an empty password hash, effectively bypassing authentication.
This is distinct from SEC-080 (which detects literal empty strings) by specifically tracking the data flow from the GET/POST default parameter through to the set_password sink.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Silent Authentication Bypass on Missing Form Field
When a registration form is submitted without the password field (intentionally or due to a client-side bug), request.POST.get('password', '') returns '' and set_password('') creates a valid empty-password hash. The user can log in without providing any password, bypassing authentication silently with no error logged.
API Client Misuse Creating Unprotected Accounts
API clients that programmatically create user accounts by POSTing JSON may omit the password field if their integration code has a bug. The server creates the account with an empty password rather than rejecting the request, creating unprotected accounts that an attacker can discover and use.
Batch User Provisioning Vulnerabilities
Bulk user import scripts that read from CSV files or external APIs may produce empty strings for missing password fields. If these empty strings flow to set_password(), the batch creates unprotected accounts for the affected users.
Race Condition in Multi-Step Registration
Multi-step registration flows that store partial state between steps may temporarily create accounts with empty passwords if the password step is bypassed or skipped due to a flow logic error. Empty string defaults in set_password() calls make this transient state permanent.
How to Fix
Recommended remediation steps
- 1Use request.POST.get('password') without a default value, so missing fields return None rather than an empty string.
- 2After retrieving the password value, check if it is None, empty, or whitespace-only and return a 400 error immediately.
- 3Apply Django's validate_password() to enforce minimum strength requirements before calling set_password().
- 4Never use '' as the default value for password fields in request.POST.get() or request.GET.get() calls.
- 5For optional password fields in update forms, distinguish between "user wants to keep current password" (field absent) and "user wants to set a new password" (field present) using None/empty checks rather than defaulting to empty string.
Detection Scope
How Code Pathfinder analyzes your code for this vulnerability
This rule performs inter-procedural taint analysis with global scope. The source is specifically calls("request.POST.get") and calls("request.GET.get") where the second argument (default value) is a literal empty string '', tracked via .tracks(0) on the return value when the field is missing. The sink is calls("*.set_password") where this tainted value reaches the first argument. Sanitizers include truthiness checks (if not password, if password is None, if password) that would reject the empty string before it reaches set_password(). The rule follows taint across function call 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 Default Empty Password Value via flows()
New feature
Get these findings posted directly on your GitHub pull requests
The Django Default Empty Password Value via flows() rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.