{"title":"Jinja2 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 for compliance audit</p>\"\n    return render_template_string(report_template)","explanation":"User-controlled input from request.args.get('filter') is directly interpolated into an f-string to construct a Jinja2 template, which is then rendered using render_template_string(). This allows attackers to inject arbitrary Jinja2 template expressions that will be executed server-side, potentially leading to remote code execution.","remediation":"The fix eliminates the template injection by passing user input as a context variable to render_template_string() instead of interpolating it directly into the template string via an f-string. Jinja2 automatically escapes context variables passed this way, preventing any injected template expressions from being interpreted as Jinja2 code. The template now uses the safe {{ bucket_filter }} placeholder syntax which treats the value as data, not executable template code.","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 for compliance audit</p>\"\n    return render_template_string(report_template, bucket_filter=bucket_filter)"}