Server-side template injection (SSTI) occurs when an attacker exploits native template syntax to inject and execute a malicious payload on the server.
Most template languages support a ‘text’ context where you can directly input HTML
http://vulnerable-website.com/?username=userThe server:
render('Hello ' + username)
Hello userYou might think to test for XSS, but it can also be vulnerable to template injection. If you find XSS, test also for SSTI. So, you should try:
http://vulnerable-website.com/?username=${7*7}If the output is 49, it means the mathematical
operation is being processed server-side.
This context is easily missed during assessment because it doesn’t result in obvious XSS.
First establish that the parameter doesn’t contain a direct XSS vulnerability by injecting HTML
http://vulnerable-website.com/?greeting=data.username<tag>Without XSS, this usually results in a blank output, encoded tags, or an error message.
Next, break out of the statement with common templating syntax and inject arbitrary HTML
http://vulnerable-website.com/?greeting=data.username}}<tag>If this results in an error or blank output, you may have used the wrong templating syntax, or SSTI isn’t possible. If the output renders correctly with the arbitrary HTML, it indicates a SSTI vulnerability.
Hello user<tag>Exploit
http://vulnerable-website.com/?greeting=data.username}}<PAYLOAD>${7*7}a{*comment*}b${7*7}${"z".join("ab")}{{7*7}} returns error{{7*'7'}} returns 7777777{{7*7}} returns 49{{7*'7'}} returns 49<%= 7*7 %> returns 49${7*7}{{7*'7'}}${7*7} -> {{7*'7'}} Note: There are many other template languages.