python.django.security.injection.ssrf.ssrf-injection-requests.ssrf-injection-requests
semgrep
Author
6,591
Download Count*
License
Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. See https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to learn more about SSRF vulnerabilities.
Run Locally
Run in CI
Defintion
rules:
- id: ssrf-injection-requests
message: Data from request object is passed to a new server-side request. This
could lead to a server-side request forgery (SSRF). To mitigate, ensure
that schemes and hosts are validated against an allowlist, do not forward
the response to the user, and ensure proper authentication and
transport-layer security in the proxied request. See
https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to
learn more about SSRF vulnerabilities.
metadata:
cwe:
- "CWE-918: Server-Side Request Forgery (SSRF)"
owasp:
- A10:2021 - Server-Side Request Forgery (SSRF)
references:
- https://owasp.org/www-community/attacks/Server_Side_Request_Forgery
category: security
technology:
- django
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- vuln
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Server-Side Request Forgery (SSRF)
languages:
- python
severity: ERROR
patterns:
- pattern-inside: |
def $FUNC(...):
...
- pattern-either:
- pattern: requests.$METHOD(..., $S.format(..., request.$W.get(...), ...), ...)
- pattern: requests.$METHOD(..., $S % request.$W.get(...), ...)
- pattern: requests.$METHOD(..., f"...{request.$W.get(...)}...", ...)
- pattern: requests.$METHOD(..., request.$W.get(...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
requests.$METHOD(..., $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
requests.$METHOD(..., $STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR.format(..., $DATA, ...)
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
requests.$METHOD(..., $STR % $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR % $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
requests.$METHOD(..., f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = f"...{$DATA}..."
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
requests.$METHOD(..., $STR + $DATA, ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = $STR + $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: $A = requests.$METHOD(..., request.$W.get(...), ...)
- pattern: return requests.$METHOD(..., request.$W.get(...), ...)
- pattern: requests.$METHOD(..., $S.format(..., request.$W(...), ...), ...)
- pattern: requests.$METHOD(..., $S % request.$W(...), ...)
- pattern: requests.$METHOD(..., f"...{request.$W(...)}...", ...)
- pattern: requests.$METHOD(..., request.$W(...), ...)
- pattern: |
$DATA = request.$W(...)
...
requests.$METHOD(..., $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
requests.$METHOD(..., $STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR.format(..., $DATA, ...)
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
requests.$METHOD(..., $STR % $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR % $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
requests.$METHOD(..., f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = f"...{$DATA}..."
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
requests.$METHOD(..., $STR + $DATA, ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = $STR + $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: $A = requests.$METHOD(..., request.$W(...), ...)
- pattern: return requests.$METHOD(..., request.$W(...), ...)
- pattern: requests.$METHOD(..., $S.format(..., request.$W[...], ...), ...)
- pattern: requests.$METHOD(..., $S % request.$W[...], ...)
- pattern: requests.$METHOD(..., f"...{request.$W[...]}...", ...)
- pattern: requests.$METHOD(..., request.$W[...], ...)
- pattern: |
$DATA = request.$W[...]
...
requests.$METHOD(..., $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
requests.$METHOD(..., $STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR.format(..., $DATA, ...)
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
requests.$METHOD(..., $STR % $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR % $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
requests.$METHOD(..., f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = f"...{$DATA}..."
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
requests.$METHOD(..., $STR + $DATA, ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = $STR + $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: $A = requests.$METHOD(..., request.$W[...], ...)
- pattern: return requests.$METHOD(..., request.$W[...], ...)
- pattern: requests.$METHOD(..., $S.format(..., request.$W, ...), ...)
- pattern: requests.$METHOD(..., $S % request.$W, ...)
- pattern: requests.$METHOD(..., f"...{request.$W}...", ...)
- pattern: requests.$METHOD(..., request.$W, ...)
- pattern: |
$DATA = request.$W
...
requests.$METHOD(..., $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W
...
requests.$METHOD(..., $STR.format(..., $DATA, ...), ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR.format(..., $DATA, ...)
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W
...
requests.$METHOD(..., $STR % $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR % $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W
...
requests.$METHOD(..., f"...{$DATA}...", ...)
- pattern: |
$DATA = request.$W
...
$INTERM = f"...{$DATA}..."
...
requests.$METHOD(..., $INTERM, ...)
- pattern: |
$DATA = request.$W
...
requests.$METHOD(..., $STR + $DATA, ...)
- pattern: |
$DATA = request.$W
...
$INTERM = $STR + $DATA
...
requests.$METHOD(..., $INTERM, ...)
- pattern: $A = requests.$METHOD(..., request.$W, ...)
- pattern: return requests.$METHOD(..., request.$W, ...)
Examples
ssrf-injection-requests.py
def test_bad_1():
from requests import get
from django.shortcuts import render
def send_to_redis(request):
# ruleid: ssrf-injection-requests
bucket = request.GET.get("bucket")
inner_response = get("http://my.redis.foo/{}".format(bucket), data=3)
return render({"response_code": inner_response.status_code})
def test_bad_2():
from requests import get
from django.http import HttpResponse
def send_to_redis(request):
# ruleid: ssrf-injection-requests
bucket = request.GET.get("bucket")
inner_response = get("http://my.redis.foo/{}".format(bucket), data=3)
return HttpResponse(body = {"response_code": inner_response.status_code})
def test_bad_3():
from requests import get
from django.shortcuts import render
def send_to_redis(request):
# ruleid: ssrf-injection-requests
bucket = request.GET.get("bucket")
inner_response = get(f"http://my.redis.foo/{bucket}", data=3)
return render({"response_code": inner_response.status_code})
def test_bad_4():
from requests import get
from django.shortcuts import render
def send_to_redis(request):
# ruleid: ssrf-injection-requests
bucket = request.headers.get("bucket")
inner_response = get("http://my.redis.foo/{}".format(bucket), data=3)
return render({"response_code": inner_response.status_code})
def test_bad_5():
from requests import get
from django.shortcuts import render
def send_to_redis(request):
# ruleid: ssrf-injection-requests
bucket = request.GET["bucket"]
inner_response = get("http://my.redis.foo/{}".format(bucket), data=3)
return render({"response_code": inner_response.status_code})
def test_bad_6():
from requests import get
from django.shortcuts import render
def send_to_redis(request):
# ruleid: ssrf-injection-requests
bucket = request.headers["bucket"]
inner_response = get("http://my.redis.foo/{}".format(bucket), data=3)
return render({"response_code": inner_response.status_code})
Short Link: https://sg.run/YvY4