RSTR-SSTI-001 — Python render_template_string / Template(req.x)
Summary
User input becomes the template source itself, not the
data rendered by a static template. Jinja2 and the Python
string.Template family give the template author the power
to execute Python expressions; if the attacker writes the
template, the attacker runs Python on the server.
SSTI commonly escalates to remote code execution via the classic payload:
{{ ''.__class__.__mro__[1].__subclasses__() }}
…which walks Python's class hierarchy to find subclasses
like subprocess.Popen and execute shell commands.
Severity
High.
Languages
Python.
What rastray flags
Template(request.x)(constructor takes user input)jinja2.Template(request.x)render_template_string(request.x)(Flask convenience)env.from_string(request.x)(Jinja2 Environment)
How to fix it
Load templates from disk and pass user input as data:
# SAFE — the template is a static file, user input is a variable
return render_template('home.html', name=request.args.get('name'))
{# templates/home.html #}
<h1>Hello, {{ name }}</h1> {# auto-escaped #}
render_template (no _string) is the safe sibling. The
template author and the request submitter must be different
people.