Django SSRF via requests Library

HIGH

User input flows to requests.get/post/put/delete/head(), enabling the server to make HTTP requests to attacker-controlled URLs.

Rule Information

Language
Python
Category
Django
Author
Shivasurya
Shivasurya
Last Updated
2026-03-22
Tags
pythondjangossrfrequestshttp-clienttaint-analysisinter-proceduralCWE-918OWASP-A10
CWE References

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-030 --project .
1
2
3
4
5
6
rule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

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 the URL argument of the requests library (requests.get(), requests.post(), requests.put(), requests.delete(), requests.head(), requests.Session().get()).

SSRF occurs when an application fetches resources from a URL that an attacker controls. The server-side HTTP request originates from inside the application's network, allowing attackers to: access cloud provider metadata endpoints (http://169.254.169.254/), reach internal services not exposed to the internet, bypass network firewalls that trust the application server, scan the internal network topology, and in some cases read sensitive files via file:// URLs.

In cloud environments (AWS, GCP, Azure), the instance metadata service is a particularly dangerous target. An attacker can use SSRF to retrieve IAM credentials, user-data scripts containing secrets, and other sensitive configuration from the metadata endpoint.

Security Implications

Potential attack scenarios if this vulnerability is exploited

1

Cloud Metadata Service Credential Theft

Cloud providers expose instance metadata at http://169.254.169.254/ (AWS, GCP) or http://169.254.169.254/metadata/ (Azure). An attacker who controls the URL can make the application fetch its own IAM credentials, which can then be used to access all AWS S3 buckets, RDS databases, and other cloud resources the application role can access.

2

Internal Network Service Scanning and Access

The application server typically has access to internal services like Redis, Elasticsearch, databases, and admin panels that are not exposed to the internet. SSRF enables attackers to send requests to these internal services, potentially triggering unauthenticated operations on Redis (FLUSHALL), Elasticsearch (index deletion), or internal admin endpoints.

3

Sensitive File Read via file:// Scheme

Some HTTP client libraries honor file:// URLs, allowing SSRF to read local files from the application server, including /etc/passwd, application secrets, private keys, and Django settings files containing database credentials.

4

Security Control Bypass via Internal Endpoints

Internal microservices often skip authentication for requests from trusted internal IP ranges. SSRF bypasses perimeter security by making the trusted application server send the request, allowing attackers to invoke privileged internal API endpoints without credentials.

How to Fix

Recommended remediation steps

  • 1Validate user-supplied URLs against a strict allowlist of trusted domains before making server-side HTTP requests.
  • 2Block all requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), loopback (127.0.0.0/8), and link-local (169.254.0.0/16) addresses.
  • 3Restrict allowed URL schemes to http and https only, blocking file://, gopher://, ftp://, and other schemes.
  • 4Set allow_redirects=False and validate redirect targets separately, as redirects can bypass initial URL validation.
  • 5Consider using an egress proxy or network-level controls to restrict outbound HTTP requests to known-safe destinations regardless of application logic.

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("requests.get"), calls("requests.post"), calls("requests.put"), calls("requests.delete"), calls("requests.head"), calls("requests.request"), and calls("requests.Session.get") with tainted URL argument tracked via .tracks(0). Sanitizers include URL validation functions that check against allowlists and block private IP ranges. The rule follows taint across file and module boundaries.

Compliance & Standards

Industry frameworks and regulations that require detection of this vulnerability

OWASP Top 10
A10:2021 - Server-Side Request Forgery (SSRF) - standalone category since 2021
CWE Top 25
CWE-918 - Server-Side Request Forgery in dangerous weaknesses list
PCI DSS v4.0
Requirement 6.2.4 - protect against injection attacks including SSRF
NIST SP 800-53
SC-7: Boundary Protection; SI-10: Information Input Validation
AWS Well-Architected Framework
SEC 5: Protect network resources - prevent unauthorized outbound requests

References

External resources and documentation

Similar Rules

Explore related security rules for Python

Frequently Asked Questions

Common questions about Django SSRF via requests Library

Cloud providers expose instance metadata at a well-known link-local address (169.254.169.254 on AWS and GCP). This service returns IAM credentials, user-data scripts, and other sensitive configuration. An SSRF vulnerability can fetch these credentials in a single request, giving attackers access to all cloud resources the application role can access.
Yes. DNS rebinding attacks involve a domain that initially resolves to a safe IP but subsequently resolves to an internal IP after validation. To protect against this, resolve the hostname to an IP at validation time and block requests if the resolved IP falls in a protected range. Re-validate after any redirect. Alternatively, use an egress proxy that enforces destination restrictions at the network level.
No. Timeout prevents the application from waiting too long for a response but the request still reaches its destination. A short timeout reduces the window for slow responses but does not prevent the attacker's target from processing the request or returning credentials from the metadata service.
Yes. Set allow_redirects=False and if your use case requires following redirects, validate each redirect destination against the same URL policy as the original request. Attackers use open redirectors on trusted domains to bypass URL allowlists: the initial request goes to allowed-domain.com/redirect?url=169.254.169.254.
Implement a webhook URL registration and verification flow: users register a URL through a separate authenticated endpoint, the application sends a one-time verification token to that URL to confirm ownership, and only verified URLs are accepted for future webhook deliveries. This prevents SSRF while allowing legitimate webhook functionality.
SEC-030 targets the popular third-party requests library, which is used by the majority of Django applications that make outbound HTTP calls. SEC-031 targets Python's standard library urllib.request.urlopen(). Both are SSRF vectors but require separate sink patterns in the rule engine to detect.
The current rule traces taint from HTTP request parameters in real-time flows. Second-order SSRF (where a URL is stored from user input and later fetched) is a separate detection challenge. Audit all places where database-stored URLs are passed to requests calls as a complementary manual review step.

New feature

Get these findings posted directly on your GitHub pull requests

The Django SSRF via requests Library rule runs in CI and posts inline review comments on the exact lines — no dashboard, no SARIF viewer.

See how it works