Problem Framing
Server-Side Template Injection (SSTI) is a critical web security vulnerability that allows an attacker to inject malicious code into a server-side template, leading to arbitrary code execution on the server. This can range from information disclosure to complete system compromise. Template engines are ubiquitous in modern web development for rendering dynamic content, making them a frequent target for attackers [1][2][3][4][5][6]. The core of SSTI lies in the improper handling of user-controlled input within these templating systems, where data is mistakenly interpreted as executable code rather than plain text. This often occurs when developers directly concatenate user input into template strings without adequate sanitization, validation, or isolation [7][8][3][9][5][10][6]. Unlike Cross-Site Scripting (XSS), which targets the client's browser, SSTI directly attacks the server, posing a more severe threat [7][3].
Core Mechanics
At its heart, SSTI exploits the intended functionality of template engines: to dynamically generate content by evaluating expressions and variables within a template. When user input bypasses the intended data-handling mechanisms and is instead processed as part of the template's executable logic, the vulnerability arises [7][8][3][4][5][10][6]. This typically involves injecting specially crafted strings that leverage the template engine's syntax to execute arbitrary code or access sensitive system resources.
The process generally follows these stages:
- Identification of Input Points: Attackers first identify user-controllable input fields, URL parameters, headers, or other data sources that are reflected in server-side generated content.
- Template Engine Detection: Basic template syntax (e.g.,
{{77}},${77},<%= 7*7 %>) is injected to determine if the server evaluates these expressions. The specific syntax and response (e.g., an arithmetic result, an error message revealing the engine type) help identify the underlying template engine (e.g., Jinja2, Twig, FreeMarker, ERB) [7][8][4][11][12][6]. Error messages can be particularly revealing, often disclosing the template engine's name, version, or even file paths within the application's structure [7]. - Exploitation of Syntax and Objects: Once the template engine is identified, attackers leverage its specific syntax and available objects to craft payloads. These payloads aim to access sensitive information, execute operating system commands, read/write files, or achieve remote code execution (RCE) [2][8][3][4][5][10][6]. Many template engines provide access to built-in objects like
request,config,self, orapplication, which can be used for introspection and to pivot to higher-level functionalities [7][8][3][9][10][13][14][6].
The danger of SSTI is amplified by the fact that many template engines offer powerful features, including access to reflection APIs, file system operations, and direct OS command execution, often designed for legitimate templating tasks but exploitable by attackers [2][3][10][6].
Notable Techniques
The exploitation of SSTI vulnerabilities is highly dependent on the specific template engine and the surrounding application logic. However, several common techniques and patterns emerge across different environments:
Accessing and Chaining Objects
A cornerstone of SSTI exploitation involves navigating the object model provided by the programming language and template engine to reach sensitive functions or classes. In Python environments leveraging Jinja2, this often involves accessing built-in types like str or dict and then traversing their Method Resolution Order (__mro__) and subclasses (__subclasses__) to find exploitable classes like _io.FileIO for file operations or classes within subprocess or os for command execution [3][9][15][10][16][13][14].
For instance, a common Jinja2 RCE payload might look like:
{{ ''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read() }} [3]
This payload leverages the str object (''), its class (__class__), its method resolution order to get to the base object class (__mro__[1]), then lists its subclasses (__subclasses__) to find the FileIO class (often at index 40 in older Python versions, though this can vary) to read /etc/passwd.
Similarly, in Java applications using FreeMarker, attackers can leverage classes like freemarker.template.utility.Execute or freemarker.template.ObjectWrapper to achieve RCE [7][17][10][18][19]. A typical FreeMarker RCE payload often involves instantiating the Execute class:
${"freemarker.template.utility.Execute"?new()("id")} [7][10]
Sandbox Escapes
Many template engines implement sandboxing mechanisms or rely on secure configurations to limit the scope of available functions and objects. Bypassing these sandboxes is a critical technique for achieving RCE.
- Jinja2 Sandbox Bypasses: Bypassing Jinja2's sandbox often involves finding alternative ways to access built-in functions or objects that might have been blacklisted or restricted. Techniques include using
request.application.__globals__.__builtins__.__import__('os').popen('id').read()to access theosmodule via therequestobject, or leveragingattr()filters to access methods that are normally inaccessible [9][20][21][16][13]. Filter bypasses can involve character encoding, string concatenation, or using alternative syntaxes likerequest[request.args.param]instead ofrequest.param[20][22]. - Twig Sandbox Escapes: Twig's sandbox can be bypassed by exploiting features like
registerUndefinedFilterCallbackor by manipulating the_selfobject to access the environment and register dangerous callbacks, such assystem[7][23][24][25][26][18][12][27]. In Grav CMS, for example, a combination of weak regex sanitization and the ability to manipulatesystem.twig.safe_filtersallowed for RCE [24][25]. - FreeMarker Sandbox Escapes: For FreeMarker, sandbox bypasses often revolve around finding classes that can be used for reflection or method invocation, such as
freemarker.template.ObjectWrapperor custom class loaders to access restricted classes likefreemarker.template.utility.Execute[17][18][19]. The?lower_abcor?upper_abcbuilt-in functions can be used to encode characters and bypass blacklisting filters [18]. - Thymeleaf Sandbox Bypasses: A notable Thymeleaf vulnerability (CVE-2026-40478) involved bypassing the sandbox via a tab character in
new[TAB]. This allowed instantiation of classes likeFileSystemResourceto write files, potentially leading to RCE [28]. Another technique involves exploiting expression preprocessing (__...__) in conjunction with controllable input to achieve double evaluation and execute malicious expressions [29][30][19].
Blind SSTI
In scenarios where template output is not directly visible, attackers can use blind SSTI techniques. These rely on inducing observable side effects, such as time delays (via sleep commands) or DNS lookups to an attacker-controlled server, to confirm vulnerability and exfiltrate data [31][32][12][6].
Leveraging Specific Objects and Methods
- Java Reflection (
ReflectionUtils): In Java applications, especially when using Spring Boot, exploiting SSTI often involves usingorg.springframework.util.ReflectionUtilsto find and invoke methods on classes, even if they are private or normally inaccessible. This can be used to accessjava.lang.Runtimeand execute commands [33][34][30][19]. - Ruby
selfand Metaprogramming: In Ruby/ERB applications, theselfobject can provide access to controller methods and instance variables, allowing introspection of available functions and data. This can lead to RCE or sensitive data disclosure [35][36][37]. - Go Template Gadgets: In Go, SSTI exploitation often involves understanding the available methods on structs passed to the template engine. For example, calling methods on
echo.Contextorgin.Contextcould lead to file reads or XSS [38][39][40]. - Jelly (ServiceNow): In ServiceNow, SSTI vulnerabilities in Jelly templates allow attackers to inject payloads that manipulate data and execute arbitrary code, often via chained vulnerabilities [41][42].
Filter Bypasses
Attackers often encounter blacklists designed to prevent common SSTI payloads. Bypassing these filters is crucial. Techniques include:
- Character Encoding: Using hexadecimal or other encodings for characters in blacklisted strings (e.g.,
\x5ffor_) [9][20][22][43]. - String Concatenation: Splitting payloads into smaller parts and reassembling them using template engine functions like
joinorformat[20][21]. - Alternative Access Methods: Using bracket notation (
request['__class__']) orattr()filters instead of dot notation (request.__class__) [20][22][16]. - Obfuscation: Employing various syntactic tricks and built-in functions to mask malicious code [20][18][44].
Detection and Prevention
Detecting and preventing SSTI requires a multi-faceted approach, combining secure coding practices, diligent input validation, and robust security testing.
Detection Strategies
- Fuzzing with Template Syntax: The primary detection method involves injecting common template syntax strings (e.g.,
{{77}},${77},<%= 7*7 %>) into user input fields and observing the server's response. A successful evaluation (e.g., rendering49instead of the literal string) indicates a potential SSTI vulnerability [7][8][4][45][10][11][12][6]. - Error-Based Detection: Intentionally injecting malformed template syntax or characters that are known to break template parsing (e.g.,
{{<%[%'"}}%\.) can trigger verbose error messages. These errors often reveal the template engine in use and potential vulnerabilities [7][31][11][12][6]. - Time-Based and Boolean-Based Detection: In blind scenarios, timing attacks (using
sleepcommands) or boolean logic (conditional execution that results in different responses) can confirm the presence of SSTI [31][45][12][6]. - Static Analysis (SAST): Scanning source code for patterns indicative of unsafe template rendering, such as direct concatenation of user input into template strings or the use of functions like
render_template_string()in Flask, can proactively identify vulnerabilities [10][46]. - Dynamic Analysis (DAST) and Automated Tools: Tools like Tplmap and SSTImap automate the process of detecting and exploiting SSTI across various template engines by sending a battery of payloads and analyzing responses [7][31][47][48][49][50][12].
- Code Review: Manually reviewing code for insecure handling of user input within template processing logic is crucial, especially for custom template engines or complex templating scenarios [8][4][5].
Prevention Strategies
- Avoid Direct Input Interpolation: The most effective prevention is to never directly embed unsanitized user input into template strings. Instead, always pass user input as distinct data variables to the template engine [1][7][8][3][4][9][37][47][5][10][16][51][6].
- Prefer
render_template()overrender_template_string(): In Flask, usingrender_template('template.html', variable=user_input)is significantly safer thanrender_template_string(f'Hello, {user_input}')[3][47][52][10]. - Input Validation and Sanitization: Strictly validate and sanitize all user input before it is passed to the template engine. This includes filtering out special characters or patterns commonly used in template syntax [1][8][4][5][10][51][6].
- Utilize Sandbox Environments: Many template engines offer sandboxing features that restrict access to dangerous functions or objects. When user-supplied templates are a business requirement, enable and configure these sandboxes appropriately [8][5][52][51][53][27].
- Disable Dangerous Features: Turn off or restrict features that enable arbitrary code execution or class instantiation if they are not strictly necessary for the application's functionality [17][5][54].
- Keep Dependencies Updated: Ensure that template engine libraries and related frameworks are kept up-to-date with the latest security patches, as new vulnerabilities are frequently discovered and fixed [28][8][46].
- Content Security Policy (CSP): Implementing a strong CSP can help mitigate the impact of client-side template injection and, in some cases, server-side template injection by restricting the execution of unauthorized scripts or resources [46].
- Web Application Firewalls (WAFs): WAFs can provide an additional layer of defense by detecting and blocking common SSTI payloads and patterns [5].
Tooling
Several tools are instrumental in detecting, identifying, and exploiting SSTI vulnerabilities:
- Tplmap: A well-established Python-based tool for detecting and exploiting SSTI and code injection vulnerabilities across numerous template engines. It automates the process of identifying the engine, injection point, and executing various exploitation techniques, including OS shell access [7][31][47][48][50][12][6].
- SSTImap: A Python 3 alternative to Tplmap, offering an interactive interface and enhanced features for SSTI detection and exploitation [7][31][49].
- Hackmanit/TInjA: An SSTI and Cross-Site Scripting (CSI) scanner that utilizes novel polyglots for detection [31][45].
- PayloadsAllTheThings Repository: A comprehensive resource for SSTI payloads and techniques across various languages and template engines, invaluable for exploitation [31][4][9][36][55][45][16][19][56].
- PortSwigger Web Security Academy Labs: Offers practical, hands-on labs designed to teach SSTI detection and exploitation techniques in a controlled environment [57][6].
- Burp Suite / OWASP ZAP: These web application security scanners can be configured with extensions or custom scripts to aid in the fuzzing and detection of SSTI vulnerabilities [12][6].
Recent Developments
The landscape of SSTI vulnerabilities is continually evolving, with new research uncovering novel bypasses, engine-specific exploits, and high-profile CVEs.
- Thymeleaf Sandbox Bypass (CVE-2026-40478): A significant vulnerability in Thymeleaf allowed sandbox escape through a tab character, enabling RCE. This highlighted the importance of scrutinizing whitespace handling and class filtering in templating engines [28].
- Jinja2 Filter Bypasses: Researchers have detailed advanced techniques for bypassing Jinja2's blacklists by abusing string manipulation functions, alternative attribute access methods, and character encoding [20][22][58][21][16][13].
- Java Sandbox Escapes: Exploiting SSTI in Java often requires sophisticated use of reflection APIs (e.g.,
ReflectionUtils,MethodUtils) to bypass sandbox restrictions and access sensitive classes likejava.lang.Runtime[34][30][19]. - Go SSTI Research: While less explored than other languages, SSTI in Go's built-in templating engines has gained attention, with research focusing on method calls on structs passed to templates and the use of custom function maps to achieve RCE or file access [38][39][40].
- ServiceNow Vulnerabilities (CVE-2024-4879, CVE-2024-5217): Critical SSTI vulnerabilities in ServiceNow allowed unauthenticated RCE by chaining multiple exploits, including Jelly template injection and filesystem filter bypasses, impacting thousands of instances [41][59][42].
- Strapi CVE-2023-22621: This vulnerability in Strapi's Users-Permissions plugin allowed SSTI to RCE via Twig email templates, often requiring an authenticated attacker with page editing privileges [23][24][25][60][26].
- Grav CMS SSTI: Exploits in Grav CMS demonstrated bypassing Twig sandboxes through weak regex sanitization, enabling RCE for authenticated users with editor permissions [23][24][25][26].
- Apache Camel Vulnerabilities (CVE-2020-11994): Multiple components within Apache Camel (FreeMarker, Velocity, MVEL, Mustache) were found to be vulnerable to SSTI, allowing RCE or arbitrary file disclosure through headers or resource URIs [61].
- OpenMetadata RCE via FreeMarker: A critical RCE vulnerability was found in OpenMetadata's email templates due to unsafe FreeMarker template instantiation, allowing authenticated admins to execute arbitrary commands [54].
Where to Go Deeper
For those looking to expand their knowledge of Server-Side Template Injection, the following resources provide in-depth analysis, practical examples, and hands-on learning opportunities:
- PortSwigger Web Security Academy: Offers a comprehensive set of labs and articles dedicated to understanding and exploiting SSTI, covering various template engines and exploitation techniques [57][51][53][27][6].
- HackTricks: A vast repository of security knowledge, including detailed guides and cheat sheets on SSTI for popular engines like Jinja2, Twig, and FreeMarker, often with practical payload examples [13][62][53].
- PayloadsAllTheThings Repository: An essential resource for a wide array of SSTI payloads, filter bypasses, and general web exploitation techniques, categorized by language and template engine [31][9][55][45][19][56].
- James Kettle's Research: James Kettle's foundational work, including "Server-Side Template Injection: RCE For The Modern Web App," laid much of the groundwork for understanding SSTI and remains a critical reference [63][53][27][6].
- Community Write-ups and Blogs: Numerous security researchers and bug bounty hunters regularly publish detailed write-ups on SSTI findings, providing real-world examples and novel exploitation techniques. Websites like Medium, Xygeni, Intigriti, and Payatu are excellent sources [64][8][65][3][4][9][17][35][66][67][15][68][69][70][71][72][52][10][73][74][11][75][76][77][34][29][30][38][39][40][32][42][78][43][79][80][58][21][81][18][44].
- OWASP Testing Guide (WSTG): Provides methodologies for testing various web vulnerabilities, including SSTI [12].
- Tool Documentation: The documentation for tools like Tplmap and SSTImap offers insights into their capabilities and usage for SSTI exploitation [47][48][49][50].
- CVE Databases: Regularly checking CVE databases (e.g., Mitre CVE, NVD) for newly disclosed SSTI vulnerabilities in popular applications and libraries can provide current attack vectors and targets [28][23][82][83][17][60][84][33][85][34][42][78][79][86][61].