# Jinja2 Server-Side Template Injection via Untrusted Template Rendering

Language: Python
Severity: Critical
CWE: CWE-1336

## Source
8-9

## Flow
8-10-11

## Sink
11

## Vulnerable Code
```python
from jinja2 import Environment
from flask import Flask, request

app = Flask(__name__)

@app.route('/iot/device/status')
def render_device_status():
    device_id = request.args.get('device_id', 'unknown')
    status_msg = request.args.get('message', 'Device operational')
    template_str = f"<h2>IoT Device: {device_id}</h2><p>Status: {status_msg}</p>"
    env = Environment()
    compiled = env.from_string(template_str)
    return compiled.render()
```

## Explanation

User-controlled input from request.args.get() is directly interpolated into a Jinja2 template string using f-string formatting. When env.from_string() compiles and renders this template, attackers can inject Jinja2 template expressions that execute arbitrary Python code on the server.

## Remediation

The fix eliminates the SSTI vulnerability by using Jinja2 template placeholders ({{ device_id }}, {{ status_msg }}) instead of f-string interpolation to pass user input into the template. User-controlled values are passed as context variables to the render() method, ensuring they are treated as data rather than template code. Additionally, autoescape=True is enabled to prevent XSS attacks.

## Secure Code
```python
from jinja2 import Environment
from flask import Flask, request
from markupsafe import escape

app = Flask(__name__)

@app.route('/iot/device/status')
def render_device_status():
    device_id = request.args.get('device_id', 'unknown')
    status_msg = request.args.get('message', 'Device operational')
    template_str = "<h2>IoT Device: {{ device_id }}</h2><p>Status: {{ status_msg }}</p>"
    env = Environment(autoescape=True)
    compiled = env.from_string(template_str)
    return compiled.render(device_id=device_id, status_msg=status_msg)
```
