The Name That Ran: Server-Side Template Injection in Flask

Web & API Security Level 3/4 ~4 min October 29, 2026

The challenge

Peachtree's card page runs your name as code. Send template code like {{7*7}} as the name. Make the card print the app's SECRET_KEY.

What you'll learn

  • Detect server-side template injection with an arithmetic probe
  • Tell Jinja2 apart from other engines from its output
  • Read Flask's config object from inside a template
  • Explain why a leaked SECRET_KEY means forged sessions
  • Render user input as data, never as template code

Skills tested

Web testingTemplate injectionRequest tampering

Prerequisites

  • What a query string is
  • What a web template does

How it works

A template engine turns a template plus variables into HTML. Server-side template injection happens when user input becomes part of the template instead of a variable: the engine then evaluates whatever the user wrote.

Here the app does TEMPLATE.replace("NAME", name) and renders the result. {{7*7}} returns 49, so the input is code. The app uses Jinja's sandboxed environment, which refuses attributes starting with an underscore, so code-execution chains end in a SecurityError. But a sandbox only limits what an expression may do, not what the template was given: in Flask every template can reach config, which holds SECRET_KEY, the key that signs session cookies.

Common mistakes

  • Typing spaces. A raw space splits the request line, and gunicorn answers 400 Invalid HTTP Version. Write {{config}} or encode spaces as %20.
  • Chasing code execution. The sandbox blocks __class__ and friends; those payloads only produce the generic 500 page. The secret is already in config.
  • Stopping at 49. The arithmetic probe only proves the bug; the secret is in config.
  • Answering the database URL. The key asked for is SECRET_KEY.

How to defend against it

  • Never concatenate user input into a template string. Keep templates static and pass data as variables: render_template_string(TEMPLATE, name=name).
  • Use a sandboxed environment (jinja2.sandbox.SandboxedEnvironment) if users must author templates.
  • Rotate SECRET_KEY after a leak: every session signed with the old key can be forged.

Full solution

Pro and Max members unlock the complete step-by-step walkthrough.

Go Pro

Community stats

165 completions
85% success rate
Malekith First blood

Related Daily Hacks

35,000+ Hackers Real labs Free
Start Hacking Free or solve today's hack, no account needed