Advanced Server-Side Template Injection (SSTI) Vulnerabilities and Mitigation
1. Vulnerability Description
Server-Side Template Injection (SSTI) is a vulnerability where an application concatenates user input directly into a template without proper sanitization or sandboxing, allowing attackers to execute arbitrary code by injecting template directives. Compared to basic SSTI, advanced scenarios involve sandbox bypasses in template engines, context-aware attacks, or the abuse of advanced language features (such as Python class inheritance or Java reflection mechanisms).
2. In-Depth Vulnerability Principles
- Template Engine Workflow: Template engines (e.g., Jinja2, Thymeleaf, Freemarker) parse template syntax (e.g.,
{{ 2+2 }}) into executable code to dynamically generate pages. - Vulnerability Trigger Points: If user input (e.g., URL parameters, form data) is directly embedded into templates, attackers can insert malicious expressions (e.g.,
{{ config.items() }}) to steal data or invoke dangerous functions. - Advanced Challenges: Some engines enable sandboxing by default (e.g., Jinja2's sandbox mode), but attackers may bypass it through methods such as:
- Exploiting built-in engine methods (e.g., Python's
__subclasses__) to access sensitive classes; - Obfuscating directives via character encoding or special syntax (e.g.,
${T(java.lang.Runtime).getRuntime().exec('id')}).
- Exploiting built-in engine methods (e.g., Python's
3. Example Attack Steps (Using Jinja2)
Step 1: Detect Template Injection Points
Submit a pure expression like {{ 7*7 }} to a parameter; if the page returns "49", a vulnerability exists.
Step 2: Explore the Sandbox Environment
- Inspect built-in objects: Inject
{{ ''.__class__ }}to retrieve detailed information about the string class. - Traverse the class inheritance chain: Use
{{ ''.__class__.__mro__[1].__subclasses__() }}to obtain a list of all subclasses.
Step 3: Identify Exploitable Classes
Search the subclass list for dangerous classes (e.g.,\u003cclass 'os._wrap_close'\u003e) and locate them by index (e.g., the 40th class).
Step 4: Execute Commands
Construct a payload to invokeos.system:
{{ ''.__class__.__mro__[1].__subclasses__()[40]('cat /etc/passwd').read() }}
4. Advanced Bypass Techniques
- Character Filter Bypass: If keywords are filtered, use hexadecimal encoding (e.g.,
\x5ffor underscores) or string concatenation (e.g.,'__cla'+'ss__'). - Sandbox Escape: Exploit template engine global functions (e.g., Jinja2's
cyclerorlipsum) to access Python's__builtins__. - Context-Aware Attacks: In Thymeleaf, combine Spring Expression Language (SpEL) injections like
${T(java.lang.System).getenv()}.
5. Mitigation Strategies
- Input Validation: Strictly restrict user input format (e.g., whitelist regex matching) and prohibit special characters (
{}$). - Template-Content Separation: Separate dynamic data from template structures, using context variables (e.g.,
template.render(user=input)) instead of direct concatenation. - Sandbox Reinforcement: Enable the template engine's sandbox mode and disable dangerous methods (e.g., Jinja2's
{% sandboxed %}tag). - Code Review Tools: Use tools like Semgrep to detect template concatenation patterns in code.
6. Summary
Advanced SSTI attacks rely on in-depth exploitation of template engine internals. Mitigation requires combining input validation, sandbox isolation, and secure development practices to prevent user input from directly participating in template parsing.