HIGH server side template injectionrestifymongodb

Server Side Template Injection in Restify with Mongodb

Server Side Template Injection in Restify with Mongodb — how this specific combination creates or exposes the vulnerability

Server Side Template Injection (SSTI) in Restify with Mongodb occurs when user-controlled input is embedded into a template string that is later evaluated by a templating engine, and the resulting data is used in a Mongodb operation. Restify does not include a built-in templating engine, but applications often integrate third-party engines (e.g., handlebars, lodash templates) to construct dynamic JSON payloads before passing them to Mongodb. If these templates are not rigorously sanitized, an attacker can inject template code that alters the structure of the rendered data, leading to unexpected behavior when the document is sent to Mongodb.

Consider a Restify endpoint that accepts a username query parameter and uses a lodash template to build a response object before inserting it into a Mongodb collection:

const restify = require('restify');
const _ = require('lodash');
const { MongoClient } = require('mongodb');

const server = restify.createServer();
server.get('/user', async (req, res, next) => {
  const username = req.query.username;
  const template = _.template('{"name": "<%= username %>", "role": "user"}');
  const doc = template({ username });
  const client = new MongoClient('mongodb://localhost:27017');
  await client.connect();
  const db = client.db('appdb');
  await db.collection('users').insertOne(JSON.parse(doc));
  res.send({ inserted: true });
  return next();
});
server.listen(8080);

If the username value contains template syntax (e.g., <%= process.exit() %>), lodash’s _.template will execute JavaScript during rendering. This can lead to unintended code execution on the server before the document is passed to Mongodb. Even if no remote code execution is achieved, an attacker can manipulate the rendered JSON structure. For example, injecting <% if (true) { %>"isAdmin": true<% } %> can add privileged fields to the document, which Mongodb will store as-is. This can bypass authorization checks later if the application trusts the inserted fields.

The risk is compounded when the application uses Mongodb query operators derived from template-rendered input. An attacker might supply a payload like { "$ne": "" } in a field that is later used in a query, potentially returning unintended documents. Since SSTI affects the rendering stage before data reaches Mongodb, the database sees only the manipulated JSON. MiddleBrick scans detect such patterns by correlating OpenAPI specifications with runtime behavior, identifying endpoints where user input influences template rendering and subsequent database operations.

Mongodb-Specific Remediation in Restify — concrete code fixes

To remediate SSTI in Restify with Mongodb, avoid constructing JSON via string-based templates altogether. Use strict schema validation and parameterized data building. If templating is necessary for formatting responses, use a safe approach that does not evaluate code. Below are concrete code examples demonstrating secure practices.

1. Replace lodash templates with explicit serialization

Do not use _.template to build JSON from user input. Instead, construct the object directly and rely on JSON.stringify for serialization:

const restify = require('restify');
const { MongoClient } = require('mongodb');

const server = restify.createServer();
server.get('/user', async (req, res, next) => {
  const username = req.query.username;
  const doc = { name: username, role: 'user' };
  const client = new MongoClient('mongodb://localhost:27017');
  await client.connect();
  const db = client.db('appdb');
  await db.collection('users').insertOne(doc);
  res.send({ inserted: true });
  return next();
});
server.listen(8080);

2. Validate and sanitize input before use

Use a validation library (e.g., Ajv) to enforce strict types and patterns. Reject input containing template-like constructs if they are not expected:

const Ajv = require('ajv');
const ajv = new Ajv();
const validate = ajv.compile({
  type: 'object',
  properties: {
    username: { type: 'string', pattern: '^[a-zA-Z0-9_]{3,30}$' }
  },
  required: ['username']
});

server.get('/user', async (req, res, next) => {
  const valid = validate(req.query);
  if (!valid) {
    res.code(400).send({ error: 'Invalid username' });
    return next();
  }
  const doc = { name: req.query.username, role: 'user' };
  const client = new MongoClient('mongodb://localhost:27017');
  await client.connect();
  await client.db('appdb').collection('users').insertOne(doc);
  res.send({ inserted: true });
  return next();
});

3. Use allowlists for dynamic fields

If your application must support dynamic fields, define an allowlist and copy only permitted keys into the document sent to Mongodb:

const allowedFields = ['name', 'email', 'preferences'];
server.post('/profile', async (req, res, next) => {
  const base = { owner: req.headers['x-user-id'] };
  const doc = allowedFields.reduce((obj, key) => {
    if (Object.prototype.hasOwnProperty.call(req.body, key)) {
      obj[key] = req.body[key];
    }
    return obj;
  }, base);
  const client = new MongoClient('mongodb://localhost:27017');
  await client.connect();
  await client.db('appdb').collection('profiles').insertOne(doc);
  res.send({ inserted: true });
  return next();
});

These approaches ensure that user input never reaches the templating or query layer in an executable or structurally mutable form. MiddleBrick’s checks for BOLA/IDOR and Property Authorization can help verify that your endpoints enforce proper access controls around these Mongodb operations.

Frequently Asked Questions

Can SSTI in Restify lead to unauthorized data access in Mongodb?
Yes. If user input manipulates the structure of documents before insertion, an attacker can inject fields such as roles or permissions that Mongodb will store and later return, potentially bypassing authorization checks in the application.
Does middleBrick detect SSTI in Restify endpoints that interact with Mongodb?
middleBrick runs 12 security checks in parallel, including Property Authorization and Input Validation, which can identify endpoints where user input influences rendered templates and downstream database operations. Findings include severity, context, and remediation guidance mapped to frameworks such as OWASP API Top 10.