{"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_name = request.args.get('bucket', 'default-bucket')\n    report_title = request.args.get('title', 'S3 Bucket Analysis')\n    template_markup = f\"<html><head><title>{report_title}</title></head><body><h1>Report for: {bucket_name}</h1></body></html>\"\n    return render_template_string(template_markup)","explanation":"The application accepts user-controlled input through the 'title' parameter (line 9) and directly embeds it into a template string using an f-string (line 10), which is then passed to render_template_string() (line 11). This allows attackers to inject Jinja2 template expressions that will be executed server-side, potentially leading to remote code execution.","remediation":"The fix replaces the dangerous f-string interpolation of user input directly into the template string with Jinja2's native variable placeholders ({{ title }} and {{ bucket }}). By passing user inputs as context variables to render_template_string(), Jinja2 automatically escapes them, preventing any template expressions in user input from being interpreted as 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_name = request.args.get('bucket', 'default-bucket')\n    report_title = request.args.get('title', 'S3 Bucket Analysis')\n    template_markup = \"<html><head><title>{{ title }}</title></head><body><h1>Report for: {{ bucket }}</h1></body></html>\"\n    return render_template_string(template_markup, title=report_title, bucket=bucket_name)"}