# Server-Side Template Injection via Jinja2 render_template_string

Language: Python
Severity: Critical
CWE: CWE-1336

## Source
9

## Flow
9-10-12

## Sink
12

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

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

@app.route('/cloud/bucket-status')
def check_bucket_health():
    bucket_name = request.args.get('bucket', 'default-bucket')
    custom_msg = request.args.get('status_msg', 'Operational')
    s3_response = s3_client.list_objects_v2(Bucket=bucket_name, MaxKeys=5)
    obj_count = s3_response.get('KeyCount', 0)
    dashboard_html = f"<html><body><h2>AWS S3 Bucket Monitor</h2><p>Bucket: {bucket_name}</p><p>Objects: {obj_count}</p><div>Status: {custom_msg}</div></body></html>"
    return render_template_string(dashboard_html)
```

## Explanation

The application accepts user-controlled input via the 'status_msg' parameter and directly embeds it into an HTML template string that is then processed by render_template_string(). This allows attackers to inject Jinja2 template expressions that will be executed server-side, leading to Remote Code Execution.

## Remediation

The fix passes user-controlled variables as context parameters to render_template_string() instead of embedding them directly into the template string via f-string interpolation. Jinja2 automatically escapes variables passed through the template context using {{ }} syntax, preventing any injected template expressions from being interpreted as code.

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

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

@app.route('/cloud/bucket-status')
def check_bucket_health():
    bucket_name = request.args.get('bucket', 'default-bucket')
    custom_msg = request.args.get('status_msg', 'Operational')
    s3_response = s3_client.list_objects_v2(Bucket=bucket_name, MaxKeys=5)
    obj_count = s3_response.get('KeyCount', 0)
    dashboard_html = "<html><body><h2>AWS S3 Bucket Monitor</h2><p>Bucket: {{ bucket_name }}</p><p>Objects: {{ obj_count }}</p><div>Status: {{ custom_msg }}</div></body></html>"
    return render_template_string(dashboard_html, bucket_name=bucket_name, obj_count=obj_count, custom_msg=custom_msg)
```
