{"title":"Jinja2 Server-Side Template Injection via render_template_string()","language":"Python","severity":"Critical","cwe":"CWE-1336","source_lines":[9],"flow_lines":[9,10,11],"sink_lines":[11],"vulnerable_code":"from flask import Flask, request, render_template_string\nimport boto3\n\napp = Flask(__name__)\ns3_client = boto3.client('s3')\n\n@app.route('/cloud/bucket-report')\ndef generate_bucket_report():\n    bucket_filter = request.args.get('filter', 'all')\n    report_template = f\"<h2>AWS S3 Bucket Report</h2><p>Filter: {bucket_filter}</p><p>Generated at {{{{ timestamp }}}}</p>\"\n    return render_template_string(report_template, timestamp='2024-01-15')","explanation":"User-controlled input from request.args.get('filter') is directly embedded into a template string via f-string interpolation on line 10, then passed to render_template_string() on line 11. This allows attackers to inject Jinja2 template expressions that execute arbitrary Python code on the server.","remediation":"The fix removes the f-string interpolation that directly embedded user input into the template string. Instead, the user-controlled `bucket_filter` value is passed as a template context variable using Jinja2's native variable substitution ({{ bucket_filter }}), which automatically escapes the value and prevents template injection attacks.","secure_code":"from flask import Flask, request, render_template_string\nimport boto3\nfrom markupsafe import escape\n\napp = Flask(__name__)\ns3_client = boto3.client('s3')\n\n@app.route('/cloud/bucket-report')\ndef generate_bucket_report():\n    bucket_filter = request.args.get('filter', 'all')\n    report_template = \"<h2>AWS S3 Bucket Report</h2><p>Filter: {{ bucket_filter }}</p><p>Generated at {{ timestamp }}</p>\"\n    return render_template_string(report_template, timestamp='2024-01-15', bucket_filter=bucket_filter)"}