Sitemap
Cyber Security Write-ups

Discover amazing bug bounty write-ups, blogs, ethical hacking guides, CTF solutions, and Hack The Box walkthroughs from top ethical hackers and cybersecurity experts. Stay ahead with expert insights and practical tips!

Server-Side Template Injection (SSTI): From Sandbox Escape to Remote Code Execution

7 min readSep 22, 2026

--

A practical deep dive into advanced SSTI, exploring sandbox restrictions, object chaining, sandbox escapes, and Remote Code Execution through a PortSwigger Web Security Academy lab.

Press enter or click to view image in full size

In our previous article, we demonstrated basic Server-Side Template Injection (SSTI) and showed how simple template syntax injection can lead directly to high-impact vulnerabilities.

In real-world applications, however, developers rarely leave template engines fully exposed — they frequently introduce restrictions such as sandboxing. A sandbox attempts to limit an attacker’s reach by explicitly restricting access to dangerous objects, global functions, sensitive modules, filesystem operations, or system command execution.

In this lab, we will investigate a sandboxed template environment, map its available functionality, identify a path around the intended restrictions, and ultimately demonstrate remote code execution (RCE).

What Is a Template Sandbox?

A template sandbox is a security mechanism built into a template engine designed to safely execute untrusted template code. When users — or attackers — can control or supply template code, a sandbox isolates that code to restrict it from accessing privileged runtime capabilities.

What a Sandbox Tries to Do : A template sandbox attempts to prevent untrusted template code from executing dangerous operations, including running Operating System commands, accessing filesystem, sensetive application objects, dangerous modules and classes, arbitrary method calls, network functionality and other priviliged functionality.

Architectural Comparison :

  • Sandboxed Template Execution :
Press enter or click to view image in full size
  • Unsandboxed Template Execution :
Press enter or click to view image in full size

A sandbox isn’t necessarily removing the vulnerability. It is attempting to limit what an attacker can do after obtaining template execution.

Why Sandbox Escapes Matter?

When a template engine implements a sandbox, it changes the threat model for Server-Side Template Injection (SSTI). Understanding sandbox escapes requires looking at how exploitation paths diverge between unsandboxed and sandboxed environments.

Direct Exploitation vs. Sandbox Bypass

  • Without sandbox
SSTI
↓
Template execution
↓
Dangerous function
↓
RCE
  • With sandbox
SSTI
↓
Restricted template execution
↓
Dangerous functionality blocked

The attacker therefore needs to find another path:

SSTI
↓
Restricted environment
↓
Explore accessible objects
↓
Find unexpected capability
↓
Chain objects/methods
↓
Reach dangerous functionality
↓
RCE

The Core Idea: Sandboxing Is Only as Strong as Its Attack Surface

A template sandbox is not a magic wall. It is just a fence built around a group of connected objects. The sandbox can successfully block direct access to dangerous tools. However, it only stays secure if there is no hidden path leading back to those powerful tools.

To do their job, templates must have access to data and tools. This means they must be allowed to touch certain objects. If even one allowed object — or any chain of properties and methods you can reach from that object — eventually leads back to the main computer system, the fence breaks.

Example :

Attacker
│
▼
Template expression
│
▼
Allowed object
│
▼
Exposed method
│
▼
Returned object
│
▼
Another method
│
▼
Dangerous capability

A sandbox can successfully block 99% of dangerous imports and system calls. However, if the remaining 1% of reachable object surface contains a route back to the runtime execution environment, the sandbox fails to prevent Remote Code Execution. The security of the sandbox is defined not by what it forbids, but by the ultimate reachability of what it allows. The sandbox restricted several direct operations, but the exposed object graph still provided an unintended path to privileged functionality.

PortSwigger Lab: Advanced SSTI

Lab Objective : This lab is vulnerable to server-side template injection. To solve the lab, create a custom exploit to delete the file /.ssh/id_rsa from Carlos's home directory.

You can log in to your own account using the following credentials: wiener:peter

Get Daksh Dhamija’s stories in your inbox

Join Medium for free to get updates from this writer.

Step-1 : Understand the application

  • Firstly login into the web application with provided credentials and explore all the functionality provided with their request.
Press enter or click to view image in full size
  • There is a functionality to upload image and set it as your avatar. Try to check this without and with image, when we have tried to upload image normally it is uploaded successfully but when we try to do request without uploading any image it returns a error.
Press enter or click to view image in full size
  • The error message discloses a method called user.setAvatar(). Also take note of the file path /home/carlos/User.php

Step-2 : Identify the SSTI Injection Point

  • There is one more functionality to choose your preffered name. we wil try to inspect the request behind it using burpsuite.
Press enter or click to view image in full size
  • In Burp Repeater, open the POST request for changing your preferred name and use the blog-post-author-display parameter to set an arbitrary file as your avatar. This is our main injection point.

Step-3 : Exploiting the vulnerability

  • Change the parameter value to this user.setAvatar('/home/carlos/User.php')
  • This will give an error, to fix it we have to add image/jpg as the second file like this user.setAvatar('/home/carlos/User.php','image/jpg')
Press enter or click to view image in full size
  • Firstly do a test comment on any post you like and then Load the page containing your test comment to render the template
  • To read the file, load the avatar using GET /avatar?avatar=wiener
  • In the PHP file, Notice that you have access to the gdprDelete() function, which deletes the user's avatar. You can combine this knowledge to delete Carlos's file
Press enter or click to view image in full size

Step-4 : Solving the lab

  • Now we set our target file as user.setAvatar('/home/carlos/.ssh/id_rsa','image/jpg')
Press enter or click to view image in full size
  • Then Load the comment and send the final request with the parameter value user.gdprDelete()to deletethe file and sole the lab
Press enter or click to view image in full size
Press enter or click to view image in full size

Root Cause

The root cause of the vulnerability is the application’s unsafe handling of user-controlled input within a server-side template.

The preferred-name functionality allows attacker-controlled template syntax to be evaluated on the server. More importantly, the template has access to a developer-supplied user object containing application-specific methods. In the lab, this object exposes functionality such as setAvatar() and gdprDelete().

The vulnerability becomes more severe because these methods were made available inside a context where an attacker could control the template expression. By investigating the application’s behavior and source code, it was possible to chain these legitimate application functions together to perform unintended actions, including reading arbitrary files and ultimately deleting a file belonging to another user.

The deeper issue is therefore not simply that SSTI exists. The application exposed a powerful application object to an attacker-controlled template environment without sufficiently restricting what that object could access or what operations its methods could perform.

Security Impact

The impact of SSTI depends heavily on the objects, methods, and privileges exposed to the template.

In this lab, exploitation allows an attacker to:

  • Access developer-supplied application objects.
  • Invoke methods that were intended for legitimate application functionality.
  • Read arbitrary files from the server.
  • Disclose sensitive application source code.
  • Discover additional privileged functionality.
  • Chain application methods to perform unauthorized actions.
  • Delete files belonging to another user.

During the lab, arbitrary file access is demonstrated by using user.setAvatar() to point the avatar to /etc/passwd and later to /home/carlos/User.php. The source code then reveals the gdprDelete() functionality, which can be abused to delete the target file.

Prevention

The strongest defense is to avoid allowing users to control or submit server-side templates whenever possible. User input should be passed into a predefined template as data rather than being concatenated into the template itself.

For applications that genuinely require user-controlled templates:

  • Separate template logic from user data
    Do not concatenate untrusted input into template source.
  • Minimize the template context
    Only expose the variables and objects that the template actually requires.
  • Do not expose powerful application objects
    Objects containing file operations, database access, administrative functions, or other privileged methods should not be directly accessible from untrusted templates.
  • Use a restricted or logic-less template engine where appropriate
    Technologies such as Mustache can reduce the amount of executable logic available in templates.
  • Use sandboxing as defense-in-depth
    Sandboxing can reduce the available attack surface, but it should not be treated as the only security boundary because sandboxing untrusted template code is inherently difficult and can be bypassed.
  • Apply least privilege
    The application process should have only the filesystem and application permissions it actually needs.
  • Isolate high-risk template processing
    Where arbitrary template execution is unavoidable, additional isolation such as a locked-down container can provide another security boundary.

Conclusion

This lab demonstrates why SSTI should not be treated simply as a template-syntax problem.

The initial injection point provided access to a developer-supplied user object. By investigating the object's available methods and chaining their functionality, it was possible to move from template injection to arbitrary file access, source-code disclosure, and ultimately unauthorized file deletion.

The key lesson is that developer-supplied objects can significantly expand the attack surface of an SSTI vulnerability. Even when direct code execution is unavailable, exposed application functionality may provide alternative paths to sensitive data or security-impacting actions.

If you’d like to follow my cybersecurity learning journey, feel free to connect with me on the platforms below.

  1. GitHub: https://github.com/daksh-dhamija
  2. LinkedIn: https://www.linkedin.com/in/daksh-dhamija-12b5b83b7/

Feedback and suggestions are always appreciated.

--

--

eJPTv2 | AppSec & Web Pentesting | HTTP Request Smuggling, SSTI, Auth Bypass | 130+ PortSwigger labs, Top 4% on TryHackMe

Cyber Security Write-ups
Cyber Security Write-ups

Published in Cyber Security Write-ups

Discover amazing bug bounty write-ups, blogs, ethical hacking guides, CTF solutions, and Hack The Box walkthroughs from top ethical hackers and cybersecurity experts. Stay ahead with expert insights and practical tips!