Skip to main content

Server side template injection

Need

Prevention of server-side template injection attacks

Context

  • Usage of PHP 7.0 for server-side scripting and web development
  • Usage of Request for making HTTP requests

Description

Non compliant code

public function renderTemplate(Request $request)
{
$template = $request->input('template');
$content = $request->input('content');
$data = ['content' => $content];

return view($template, $data);
}

In the above code, we have a function renderTemplate that takes a Request object as input. This function is vulnerable to Server Side Template Injection (SSTI).

The function retrieves a template name and content from the request input using $request->input('template') and $request->input('content') respectively. It then creates an associative array $data with the content and renders the view using return view($template, $data);.

The vulnerability here lies in the fact that the server blindly trusts the user input and uses it directly to render the view. An attacker can inject malicious entries into the template by manipulating the 'template' parameter in the request. Since the server does not sanitize or validate this input before using it, this can lead to Server Side Template Injection (SSTI).

For instance, an attacker can send a request with a template parameter that contains malicious code. Since the server uses this input directly to render the view, the malicious code will be executed on the server side, leading to SSTI.

Steps

  • Validate the 'template' input to ensure it matches a list of predefined templates.
  • Sanitize the 'content' input to remove any potential malicious code.
  • Use a secure method to render the template, such as using a server-side template engine that automatically escapes output.
  • Implement a Content Security Policy (CSP) to reduce the risk of Cross-Site Scripting (XSS) attacks.
  • Regularly update and patch your server-side template engine to protect against known vulnerabilities.

Compliant code

public function renderTemplate(Request $request)
{
$allowedTemplates = ['template1', 'template2', 'template3']; // predefined templates
$template = $request->input('template');
$content = $request->input('content');

// Validate the template
if (!in_array($template, $allowedTemplates)) {
abort(403, 'Unauthorized action.');
}

// Sanitize the content
$content = e($content);

$data = ['content' => $content];

return view($template, $data);
}

The updated code includes a list of predefined templates ($allowedTemplates). When a request is made, the code checks if the requested template is in the list of allowed templates. If it's not, the code aborts the operation and returns a 403 error.

The content is sanitized using Laravel's e function, which converts special characters to their HTML entities. This prevents any potential malicious code from being executed.

The view function is a secure method to render the template. Laravel's Blade templating engine automatically escapes output, which helps prevent Cross-Site Scripting (XSS) attacks.

In addition to these code changes, it's recommended to implement a Content Security Policy (CSP) to further reduce the risk of XSS attacks. This can be done in the HTTP headers of your application.

Finally, it's important to regularly update and patch your server-side template engine to protect against known vulnerabilities. This can be done as part of your regular maintenance and update schedule.

References