# Jinja2 Template Injection via render_template_string

Language: Python
Severity: Critical
CWE: CWE-1336

## Source
9-10

## Flow
9-11-12

## Sink
12

## Vulnerable Code
```python
from flask import Flask, request, render_template_string
import boto3

iot_app = Flask(__name__)
s3_client = boto3.client('s3')

@iot_app.route('/device/status')
def fetch_device_telemetry():
    device_id = request.args.get('device_id', 'unknown')
    sensor_type = request.args.get('sensor', 'temperature')
    template_markup = f"<h2>Device {device_id} - Sensor: {sensor_type}</h2><p>Status: {{{{ status }}}}</p>"
    return render_template_string(template_markup, status='operational')
```

## Explanation

The application accepts untrusted user input from request parameters (device_id and sensor_type) and directly embeds them into a Jinja2 template string via an f-string. This template is then rendered using render_template_string(), allowing attackers to inject malicious Jinja2 expressions that execute arbitrary Python code on the server.

## Remediation

The fix removes the f-string interpolation that embedded user input directly into the template string. Instead, user-provided values (device_id and sensor_type) are passed as context variables to render_template_string(), which automatically escapes them via Jinja2's autoescaping, preventing any injected template expressions from being interpreted.

## Secure Code
```python
from flask import Flask, request, render_template_string
from markupsafe import escape
import boto3

iot_app = Flask(__name__)
s3_client = boto3.client('s3')

@iot_app.route('/device/status')
def fetch_device_telemetry():
    device_id = request.args.get('device_id', 'unknown')
    sensor_type = request.args.get('sensor', 'temperature')
    template_markup = "<h2>Device {{ device_id }} - Sensor: {{ sensor_type }}</h2><p>Status: {{ status }}</p>"
    return render_template_string(template_markup, device_id=device_id, sensor_type=sensor_type, status='operational')
```
