## https://sploitus.com/exploit?id=9A8E3221-4E63-5827-9530-5CE2496AD168
# Server-Side Template Injection (SSTI) to RCE Lab
## ๐ฏ Executive Summary
This laboratory demonstrates **Server-Side Template Injection (CWE-1336)**, a critical vulnerability that occurs when user input is unsafely embedded into a server-side template engine (such as Jinja2). The lab highlights how an attacker can escalate a simple injection flaw into full **Remote Code Execution (RCE)** by breaking out of the template sandbox.
---
## ๐๏ธ Technical Architecture
### 1. The Vulnerable Asset (`invoice_app.py` - Initial State)
The application generates a dynamic invoice using Flask and Jinja2. The vulnerability exists because the developer used Python's f-strings to concatenate user input directly into the template string before rendering it.
* **Vulnerable Pattern:** `render_template_string(f"Hello {user_input}")`
* This instructs the engine to parse and execute any template syntax provided by the user.
### 2. The Exploit Engine (`ssti_exploit.py`)
The attack is conducted in two phases:
1. **The Probe:** The script injects mathematical template syntax (`{{ 7 * 7 }}`). If the server returns `49`, the engine is actively evaluating input.
2. **The Weaponization (RCE):** The script uses Python's Method Resolution Order (MRO) to traverse the application's internal classes, access the `os` module, and execute a terminal command (`whoami`).
* **Payload used:** `{{ request.application.__globals__.__builtins__.__import__('os').popen('whoami').read() }}`
---
## ๐ก๏ธ Remediation & Architectural Defense
Template engines are designed to safely render data, but only if the data is passed as a **Context Variable** rather than being concatenated into the raw template string.
### The Professional Fix (Context Passing)
To secure the application, the `invoice_app.py` must be updated to separate the template logic from the data.
**Replace the vulnerable route with this secure implementation:**
```python
@app.route('/generate')
def secure_generate_invoice():
user_name = request.args.get('name', 'Guest')
# THE FIX: Define the template with a placeholder variable, NOT an f-string
template = '''
Invoice Generated
Thank you for your business, {{ name }}!
'''
# Pass the user input as a context variable to the engine
# The engine will safely treat it as a pure string, neutralizing execution.
return render_template_string(template, name=user_name)
```
### ๐ ๏ธ Laboratory Execution Steps
1. Clone the Repository
```bash
git clone [https://github.com/abhinandanpandey-in/SSTI-Exploit-Lab.git](https://github.com/abhinandanpandey-in/SSTI-Exploit-Lab.git)
cd SSTI-Exploit-Lab
```
2. Initialize the Environment
```bash
python -m venv venv
# Windows
.\venv\Scripts\activate
# Linux/Mac
source venv/bin/activate
pip install flask requests
```
### 3. Execute Phase 1: Exploitation
1 Start the vulnerable server: python invoice_app.py
2 In a separate terminal, run the exploit: python ssti_exploit.py
3 Observe the Breach: The exploit will output the result of the whoami command, confirming full server compromise (RCE).
### 4. Execute Phase 2: Remediation
1 Open invoice_app.py and replace the vulnerable routing logic with the Secure Implementation provided above.
2 Restart the server.
3 Run the exploit script again: python ssti_exploit.py
4 Observe the Defense: The exploit fails. The server now safely renders the literal string {{ 7 * 7 }} without executing it,
proving the template engine is no longer evaluating user input as code.