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-031 --project .About This Rule
Understanding the vulnerability and how it is detected
This rule detects Server-Side Request Forgery (SSRF) vulnerabilities in Django applications where untrusted user input from HTTP request parameters flows into urllib.request.urlopen() or urllib.request.Request() from Python's standard library.
urllib is the standard Python HTTP client and is commonly used in Django applications that do not have the third-party requests library as a dependency, or in older codebases. It is subject to the same SSRF risks as any HTTP client: an attacker who controls the URL can direct server-side requests to cloud metadata endpoints, internal services, localhost, or file:// URLs.
urllib's urlopen() additionally supports several URL schemes beyond http/https, including file:// and ftp://, which increases the attack surface compared to some other HTTP clients. The file:// scheme in particular can be used to read arbitrary files from the server's filesystem.
Security Implications
Potential attack scenarios if this vulnerability is exploited
Cloud Metadata Service Access via Standard Library
urllib.request.urlopen('http://169.254.169.254/latest/meta-data/iam/...') fetches AWS IAM credentials from the instance metadata service. Unlike the requests library, urllib is always available in any Python environment, making this vector present in any Django deployment regardless of installed packages.
Local File Disclosure via file:// Scheme
urllib.request.urlopen() supports the file:// URL scheme by default. An attacker can supply a URL like file:///etc/passwd or file:///app/settings.py to read arbitrary files from the server filesystem, potentially exposing Django's SECRET_KEY, database credentials, and other configuration secrets.
Internal Service Access and Port Scanning
The application server can reach internal network services that are not exposed to the internet. An attacker can use urlopen() to scan internal ports (observing connection errors vs. successful responses) and access internal HTTP services without authentication.
Gopher Protocol Exploitation
Some versions of urllib support the gopher:// scheme which can be used for SSRF attacks against Redis, Memcached, and other services that use text-based protocols. If gopher:// is accessible, attackers can send arbitrary TCP payloads to internal services.
How to Fix
Recommended remediation steps
- 1Validate user-supplied URLs against a strict allowlist of trusted domains before calling urlopen().
- 2Block the file://, gopher://, and ftp:// schemes -- accept only http and https.
- 3Block requests to private IP ranges, loopback addresses, and link-local networks (169.254.0.0/16).
- 4Resolve hostnames to IPs at validation time to prevent DNS rebinding attacks from bypassing scheme and domain checks.
- 5Consider replacing urllib with the requests library and its higher-level session management, which makes timeout and redirect controls more explicit.
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("urllib.request.urlopen"), calls("urllib.request.Request"), and calls("urllib.urlopen") with tainted URL argument tracked via .tracks(0). Sanitizers include URL validation functions that check against allowlists and block private IP ranges and dangerous schemes. 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 SSRF via urllib
New feature
Get these findings posted directly on your GitHub pull requests
The Django SSRF via urllib rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.