OSWA study materials
OSWA study resources

OSWA: Server-Side Template Injection (SSTI)

OSWA · Work through your exam, one topic at a time.

All guide sections

Server-Side Template Injection (SSTI)

SSTI tests whether user input is concatenated into a server-side template and evaluated. The exam expects engine identification and a path from evaluation to file read or command execution.

Core rules and concepts

  • Detection payloads vary by engine: {{7*7}} for Jinja2/Twig, ${7*7} for Freemarker and JSP EL, <%= 7*7 %> for ERB, #{7*7} for Ruby, and {7*7} for Smarty.
  • Engine confirmation: Jinja2 returns 7777777 for {{7*'7'}}, while Twig returns 49.
  • RCE paths reach Python object internals in Jinja2 (__class__, __mro__, __subclasses__, or config globals), _self in Twig, ?new() in Freemarker, and Runtime in Velocity.
  • Blind SSTI is confirmed with time delays or DNS callbacks.
  • Sandboxed environments require escape chains and filter bypasses.

Worked example

A name parameter reflects Hello {{7*7}} as Hello 49, proving evaluation. Send {{7*'7'}}; the response is 7777777, identifying Jinja2 rather than Twig. Then submit {{ cycler.__init__.__globals__.os.popen('id').read() }}, which returns uid=33(www-data). Reasoning: confirming the engine avoids sending Twig syntax to a Jinja2 target, and the globals path reaches the os module for command execution.

Traps that cost marks

  • Treating a mathematical result as proof without confirming the engine.
  • Testing only one syntax family.
  • Forgetting to URL-encode braces and quotes.
  • Giving up when underscores or quotes are filtered; use request.args, attr, or hex escapes.
  • Confusing client-side templating in Angular or Vue with server-side evaluation.