# SSTI

#### Server-Side Template Injection (SSTI)

**Example 1: Python (Flask)**

**Vulnerable Code:**

```python
pythonCopy code@app.route('/greet')
def greet():
    name = request.args.get('name')
    return render_template_string('Hello {{ name }}', name=name)
```

**Reason for vulnerability:** User input is directly used in the template, allowing SSTI.

**Fixed Code:**

```python
pythonCopy code@app.route('/greet')
def greet():
    name = request.args.get('name')
    return render_template('greet.html', name=name)
```

**Reason for fix:** Use static templates instead of rendering user input directly.

**Example 2: Python (Jinja2)**

**Vulnerable Code:**

```python
pythonCopy codefrom jinja2 import Template

template = Template("Hello {{ name }}")
output = template.render(name=request.args.get('name'))
```

**Reason for vulnerability:** User input is directly used in the template, allowing SSTI.

**Fixed Code:**

```python
pythonCopy codefrom jinja2 import Template

template = Template("Hello {{ name }}")
output = template.render(name=escape(request.args.get('name')))
```

**Reason for fix:** Escape user input before rendering the template.

***

### Java Example

#### Vulnerable Code:

```java
javaCopyimport freemarker.template.Configuration;
import freemarker.template.Template;

@Controller
public class GreetingController {
    @GetMapping("/greet")
    public String greet(@RequestParam String name, Model model) {
        String templateString = "Hello, ${name}!";
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_29);
        Template template = new Template("greeting", new StringReader(templateString), cfg);
        StringWriter writer = new StringWriter();
        template.process(Collections.singletonMap("name", name), writer);
        model.addAttribute("greeting", writer.toString());
        return "greetingPage";
    }
}
```

#### Reason for Vulnerability:

This code directly incorporates user input into a FreeMarker template, allowing potential injection of malicious templates.

#### Fixed Code:

```java
javaCopy@Controller
public class GreetingController {
    @GetMapping("/greet")
    public String greet(@RequestParam String name, Model model) {
        model.addAttribute("name", name);
        return "greetingPage";
    }
}

<!-- greetingPage.ftl -->
<h1>Hello, ${name?html}!</h1>
```

#### Reason for Fix:

The fixed code separates the template from user input and uses FreeMarker's built-in HTML escaping to prevent SSTI.

***

### Python Example

#### Vulnerable Code:

```python
pythonCopyfrom flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/greet')
def greet():
    name = request.args.get('name', 'Guest')
    template = f'''
    <h1>Hello, {name}!</h1>
    <p>Welcome to our website.</p>
    '''
    return render_template_string(template)
```

#### Reason for Vulnerability:

This code directly incorporates user input into a template string, allowing potential injection of malicious templates.

#### Fixed Code:

```python
pythonCopyfrom flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/greet')
def greet():
    name = request.args.get('name', 'Guest')
    return render_template('greet.html', name=name)

# greet.html
# <h1>Hello, {{ name|e }}!</h1>
# <p>Welcome to our website.</p>
```

#### Reason for Fix:

The fixed code uses a separate template file and Flask's automatic escaping to prevent SSTI.

### Ruby Example

#### Vulnerable Code:

```ruby
rubyCopyrequire 'sinatra'
require 'erb'

get '/greet' do
  name = params[:name] || 'Guest'
  ERB.new("<h1>Hello, <%= name %>!</h1>").result(binding)
end
```

#### Reason for Vulnerability:

This Sinatra route directly incorporates user input into an ERB template, allowing potential injection of malicious Ruby code.

#### Fixed Code:

```ruby
rubyCopyrequire 'sinatra'

get '/greet' do
  name = params[:name] || 'Guest'
  erb :greet, locals: { name: name }
end

# views/greet.erb
# <h1>Hello, <%= Rack::Utils.escape_html(name) %>!</h1>
```

#### Reason for Fix:

The fixed code uses a separate template file and Rack's HTML escaping to prevent SSTI.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://playbook.sidthoviti.com/devsecops/secure-coding/code-review-examples/ssti.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
