python.django.security.injection.code.user-exec-format-string.user-exec-format-string
semgrep
Author
8,307
Download Count*
License
Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need.
Run Locally
Run in CI
Defintion
rules:
- id: user-exec-format-string
message: Found user data in a call to 'exec'. This is extremely dangerous
because it can enable an attacker to execute arbitrary remote code on the
system. Instead, refactor your code to not use 'eval' and instead use a
safe library for the specific functionality you need.
metadata:
cwe:
- "CWE-95: Improper Neutralization of Directives in Dynamically
Evaluated Code ('Eval Injection')"
owasp:
- A03:2021 - Injection
category: security
technology:
- django
references:
- https://owasp.org/www-community/attacks/Code_Injection
subcategory:
- vuln
likelihood: MEDIUM
impact: HIGH
confidence: MEDIUM
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
patterns:
- pattern-inside: |
def $F(...):
...
- pattern-either:
- pattern: exec(..., $STR % request.$W.get(...), ...)
- pattern: |
$V = request.$W.get(...)
...
exec(..., $STR % $V, ...)
- pattern: |
$V = request.$W.get(...)
...
$S = $STR % $V
...
exec(..., $S, ...)
- pattern: exec(..., "..." % request.$W(...), ...)
- pattern: |
$V = request.$W(...)
...
exec(..., $STR % $V, ...)
- pattern: |
$V = request.$W(...)
...
$S = $STR % $V
...
exec(..., $S, ...)
- pattern: exec(..., $STR % request.$W[...], ...)
- pattern: |
$V = request.$W[...]
...
exec(..., $STR % $V, ...)
- pattern: |
$V = request.$W[...]
...
$S = $STR % $V
...
exec(..., $S, ...)
- pattern: exec(..., $STR.format(..., request.$W.get(...), ...), ...)
- pattern: |
$V = request.$W.get(...)
...
exec(..., $STR.format(..., $V, ...), ...)
- pattern: |
$V = request.$W.get(...)
...
$S = $STR.format(..., $V, ...)
...
exec(..., $S, ...)
- pattern: exec(..., $STR.format(..., request.$W(...), ...), ...)
- pattern: |
$V = request.$W(...)
...
exec(..., $STR.format(..., $V, ...), ...)
- pattern: |
$V = request.$W(...)
...
$S = $STR.format(..., $V, ...)
...
exec(..., $S, ...)
- pattern: exec(..., $STR.format(..., request.$W[...], ...), ...)
- pattern: |
$V = request.$W[...]
...
exec(..., $STR.format(..., $V, ...), ...)
- pattern: |
$V = request.$W[...]
...
$S = $STR.format(..., $V, ...)
...
exec(..., $S, ...)
- pattern: |
$V = request.$W.get(...)
...
exec(..., f"...{$V}...", ...)
- pattern: |
$V = request.$W.get(...)
...
$S = f"...{$V}..."
...
exec(..., $S, ...)
- pattern: |
$V = request.$W(...)
...
exec(..., f"...{$V}...", ...)
- pattern: |
$V = request.$W(...)
...
$S = f"...{$V}..."
...
exec(..., $S, ...)
- pattern: |
$V = request.$W[...]
...
exec(..., f"...{$V}...", ...)
- pattern: |
$V = request.$W[...]
...
$S = f"...{$V}..."
...
exec(..., $S, ...)
- pattern: exec(..., base64.decodestring($S.format(..., request.$W.get(...), ...),
...), ...)
- pattern: exec(..., base64.decodestring($S % request.$W.get(...), ...), ...)
- pattern: exec(..., base64.decodestring(f"...{request.$W.get(...)}...", ...),
...)
- pattern: exec(..., base64.decodestring(request.$W.get(...), ...), ...)
- pattern: exec(..., base64.decodestring(bytes($S.format(..., request.$W.get(...),
...), ...), ...), ...)
- pattern: exec(..., base64.decodestring(bytes($S % request.$W.get(...), ...),
...), ...)
- pattern: exec(..., base64.decodestring(bytes(f"...{request.$W.get(...)}...",
...), ...), ...)
- pattern: exec(..., base64.decodestring(bytes(request.$W.get(...), ...), ...),
...)
- pattern: |
$DATA = request.$W.get(...)
...
exec(..., base64.decodestring($DATA, ...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = base64.decodestring($DATA, ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W.get(...)
...
exec(..., base64.decodestring(bytes($DATA, ...), ...), ...)
- pattern: |
$DATA = request.$W.get(...)
...
$INTERM = base64.decodestring(bytes($DATA, ...), ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
exec(..., base64.decodestring($DATA, ...), ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = base64.decodestring($DATA, ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W(...)
...
exec(..., base64.decodestring(bytes($DATA, ...), ...), ...)
- pattern: |
$DATA = request.$W(...)
...
$INTERM = base64.decodestring(bytes($DATA, ...), ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
exec(..., base64.decodestring($DATA, ...), ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = base64.decodestring($DATA, ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W[...]
...
exec(..., base64.decodestring(bytes($DATA, ...), ...), ...)
- pattern: |
$DATA = request.$W[...]
...
$INTERM = base64.decodestring(bytes($DATA, ...), ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W
...
exec(..., base64.decodestring($DATA, ...), ...)
- pattern: |
$DATA = request.$W
...
$INTERM = base64.decodestring($DATA, ...)
...
exec(..., $INTERM, ...)
- pattern: |
$DATA = request.$W
...
exec(..., base64.decodestring(bytes($DATA, ...), ...), ...)
- pattern: |
$DATA = request.$W
...
$INTERM = base64.decodestring(bytes($DATA, ...), ...)
...
exec(..., $INTERM, ...)
languages:
- python
severity: WARNING
Examples
user-exec-format-string.py
from textwrap import dedent
def unsafe(request):
# ruleid: user-exec-format-string
message = request.POST.get('message')
print("do stuff here")
code = """
print(%s)
""" % message
exec(code)
def unsafe_inline(request):
# ruleid: user-exec-format-string
exec("print(%s)" % request.GET.get('message'))
def unsafe_dict(request):
# ruleid: user-exec-format-string
exec("print(%s)" % request.POST['message'])
def safe(request):
# ok: user-exec-format-string
code = """
print('hello')
"""
exec(dedent(code))
def fmt_unsafe(request):
# ruleid: user-exec-format-string
message = request.POST.get('message')
print("do stuff here")
code = """
print({})
""".format(message)
exec(code)
def fmt_unsafe_inline(request):
# ruleid: user-exec-format-string
exec("print({})".format(request.GET.get('message')))
def fmt_unsafe_dict(request):
# ruleid: user-exec-format-string
exec("print({}, {})".format(request.POST['message'], "pwned"))
def fmt_safe(request):
# ok: user-exec-format-string
code = """
print('hello')
"""
exec(dedent(code))
def code_execution(request):
data = ''
msg = ''
first_name = ''
if request.method == 'POST':
# Clear out a previous success to reset the exercise
try:
os.unlink('p0wned.txt')
except:
pass
# ruleid: user-exec-format-string
first_name = request.POST.get('first_name', '')
try: # Try it the Python 3 way...
exec(base64.decodestring(bytes(first_name, 'ascii')))
except TypeError:
try: # Try it the Python 2 way...
exec(base64.decodestring(first_name))
except:
pass
except:
pass
Short Link: https://sg.run/J9JW