Server Side Template Injection in Restify
How Server Side Template Injection Manifests in Restify
Server Side Template Injection (SSTI) in Restify applications occurs when user-controlled input is directly interpolated into a server-side template without proper sanitization or escaping. Restify itself is a minimalist framework and does not include a built-in templating engine; however, it is commonly paired with view engines like ejs, pug, or mustache via plugins such as restify-views. The vulnerability arises when route handlers use these engines to render templates with unsanitized request parameters.
A typical vulnerable pattern in Restify with ejs looks like this:
const restify = require('restify');
const { views } = require('restify-views');
const server = restify.createServer();
server.use(views({
engine: 'ejs',
directory: __dirname + '/views'
}));
server.get('/profile', (req, res, next) => {
// VULNERABLE: user input 'name' is passed directly to template
res.view('profile', { username: req.query.name });
return next();
});
If the views/profile.ejs template contains unescaped output like <%= username %> (which outputs raw HTML), an attacker can inject template syntax via the URL parameter, e.g., /profile?name=<%= process.env %>. This could expose environment variables, or worse, if the template engine supports JavaScript evaluation (as ejs does), an attacker might achieve remote code execution by chaining with other vulnerabilities, such as accessing require('child_process') if the template context is polluted. In Restify's case, the risk is exacerbated because the framework's plugin ecosystem may implicitly trust developer configurations, and the lack of built-in CSRF or input validation means developers must manually secure template rendering paths.
Restify-Specific Detection
Detecting SSTI in Restify APIs involves probing endpoints that render templates for unsanitized input reflection. Since Restify APIs often serve both JSON and HTML responses, SSTI may surface in routes that use res.view(). A scanner must identify these routes and test for template engine syntax execution. middleBrick's Input Validation check specifically targets this by sending payloads containing template expressions (e.g., <%= 7*7 %> for ejs, {{7*7}} for mustache) and analyzing responses for computed results or error messages that reveal template processing. For Restify applications using restify-views, the scanner also checks for misconfigured engine options that might disable escaping.
During a scan, middleBrick would:
- Crawl the API's OpenAPI/Swagger spec (if available) to identify routes returning
text/htmlcontent types, which are likely candidates for template rendering. - Send sequential probes with different template syntaxes to parameterized inputs (query, path, body) and monitor for:
- Mathematical computations (e.g.,
49from7*7) - Object property access (e.g.,
process.env.PATH) - Template engine-specific error messages (e.g.,
Unexpected tokeninejs)
- Mathematical computations (e.g.,
- Cross-reference findings with the
restify-viewsconfiguration if the spec includes custom extensions or middleware descriptions.
The scanner's report will flag this under the Input Validation category with a severity based on exploitability. For example, an endpoint that executes arbitrary JavaScript via ejs would score as High due to potential RCE. You can test this yourself using middleBrick's CLI tool:
middlebrick scan https://your-restify-api.com/profile?name=<%= 7*7 %>The resulting JSON report will indicate if the payload 49 appeared in the response, confirming SSTI. The web dashboard also visualizes this as part of the per-category breakdown.
Restify-Specific Remediation
Remediating SSTI in Restify requires a defense-in-depth approach, focusing on proper template configuration and input handling. The primary fix is to ensure all user input is escaped before reaching the template engine. For ejs with restify-views, use the escaped output tag <%- %> is actually unescaped; the safe tag is <%= %>. Wait, correction: in ejs, <%= %> escapes HTML by default, while <%- %> outputs raw HTML. Many developers confuse this. The vulnerable example used <%= username %>, which is actually escaped in ejs—so that specific code might be safe. However, if the template uses <%- username %> (unescaped), or if the developer has globally disabled escaping, the vulnerability appears. Therefore, audit your .ejs files for unescaped tags.
Here is a corrected Restify route and template:
// Route handler - pass user input as before
server.get('/profile', (req, res, next) => {
res.view('profile', { username: req.query.name });
return next();
});
In views/profile.ejs:
<h1>Profile: <%= username %></h1> <!-- ESCAPED, safe -->
<!-- NEVER use: <h1><%- username %></h1> -->Additionally, Restify developers should:
- Use a strict template engine configuration: When initializing
restify-views, setescapetotrue(thoughejsescapes by default, this reinforces intent). - Validate and sanitize input before passing to templates. For example, use a library like
validatororxssto strip or encode dangerous characters. - Prefer JSON responses for APIs: If the endpoint is part of a JSON API, avoid templates entirely and use
res.send({ username: req.query.name }). This eliminates the template injection surface. - Content Security Policy (CSP): While not a direct fix for SSTI, a restrictive CSP can mitigate the impact of any injected scripts.
For Restify applications using other template engines (e.g., pug), similar principles apply: use automatic escaping features (Pug escapes by default) and avoid !{}` unescaped interpolation. After applying fixes, re-scan with middleBrick's GitHub Action in your CI/CD pipeline to ensure the Input Validation score improves and the finding is resolved.
Understanding the Risk
Server Side Template Injection is classified under OWASP API Security Top 10 – A03:2021 – Broken Object Property Level Authorization? Actually, SSTI falls under A03:2021 – Injection. In Restify, this vulnerability can lead to severe consequences including information disclosure, remote code execution, and server compromise. The risk is heightened because Restify's plugin-based architecture may obscure template usage—developers might not realize a route renders HTML. middleBrick's scoring reflects this: an exploitable SSTI typically results in a High or Critical severity finding in the Input Validation category, dropping the overall API grade to C–F depending on context. Continuous monitoring via middleBrick's Pro plan helps detect regressions if new routes introduce unsafe template patterns.