HIGH server side template injectionadonisjsfirestore

Server Side Template Injection in Adonisjs with Firestore

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

Server Side Template Injection (SSTI) occurs when an attacker can inject template expressions that are evaluated on the server. In AdonisJS, SSTI is commonly associated with the built-in Edge view engine when user-controlled data is passed into template rendering without proper escaping or validation. If your AdonisJS application passes dynamic input into an Edge template — for example, to customize content or perform variable substitution — and that input is later rendered via View.render or similar mechanisms, an attacker may be able to execute arbitrary template code.

When Firestore is used as the backend database, the risk pattern shifts slightly. An SSTI vulnerability in AdonisJS does not require Firestore to be vulnerable; instead, Firestore becomes a data source that may feed attacker-influenced content into the template engine. For example, if an endpoint retrieves a document from Firestore based on an ID supplied by the user, and then passes fields from that document directly into an Edge template, any malicious payload stored or reflected in Firestore can trigger template injection at render time.

Consider an AdonisJS route that reads a user profile document from Firestore and renders it using Edge:

// routes.ts
Route.get('/profile/:userId', async ({ params, view }) => {
  const db = use('Firestore');
  const doc = await db.collection('profiles').doc(params.userId).get();
  const data = doc.data();
  return view.render('profile', data);
});

If the profile document contains a field like bio that was previously set by an attacker via SSTI (for example, through an earlier compromised admin interface or a malicious import), and that field is rendered unescaped in the Edge template:

{{/* profile.edge */}}
<div>{{ bio }}</div>

Then the injected template code may execute when the page is rendered, depending on how the data is handled by the Edge compiler. AdonisJS does not inherently sanitize data passed to templates, so developers must explicitly escape output or avoid passing raw user-influenced data into templates.

Additionally, if your application dynamically includes partial templates or uses template-level logic based on Firestore document fields (e.g., selecting a layout name from a document), an attacker who can influence that field may cause the server to render unintended templates, leading to information disclosure or code execution within the template context.

Because this scan tests unauthenticated endpoints, an endpoint that exposes Firestore-derived data to templates without authentication checks can be probed and exploited without credentials. This makes SSTI particularly dangerous in server-side rendered applications where templates are rendered on every request.

Firestore-Specific Remediation in Adonisjs — concrete code fixes

Remediation focuses on preventing untrusted data from reaching the template engine and ensuring that all dynamic values are handled safely when interacting with Firestore.

1. Avoid passing raw Firestore documents directly to templates. Instead, sanitize and transform data before rendering:

// routes.ts — safe approach
Route.get('/profile/:userId', async ({ params, view }) => {
  const db = use('Firestore');
  const doc = await db.collection('profiles').doc(params.userId).get();
  const data = doc.data();

  // Explicitly pick and escape fields
  const safeData = {
    username: escapeHtml(data?.username || ''),
    bio: escapeHtml(data?.bio || ''),
  };

  return view.render('profile', safeData);
});

function escapeHtml(str: string): string {
  return str.replace(/[<>"']/g, (match) => ({
    '&': '&',
    '<': '<',
    '>': '>',
    '"': '"',
    "'": ''',
  }[match]));
}

2. Validate and restrict template selection. If your app selects partials or layouts based on Firestore content, use a strict allowlist:

// routes.ts — controlled template selection
const allowedTemplates = new Set(['profile', 'dashboard', 'settings']);

Route.get('/page/:templateId', async ({ params, view }) => {
  const db = use('Firestore');
  const doc = await db.collection('templates').doc(params.templateId).get();
  const data = doc.data();

  if (!allowedTemplates.has(data?.name)) {
    throw new Error('Invalid template');
  }

  return view.render(data.name, data.payload || {});
});

3. Use parameterized queries and never inject raw strings into template logic. Firestore queries should be built with document IDs or collection names validated against a pattern, never concatenated from user input:

// Safe Firestore document retrieval
Route.get('/doc/:docId', async ({ params, view }) => {
  const db = use('Firestore');
  // Validate docId format before use
  if (!/^[a-zA-Z0-9_-]{1,100}$/.test(params.docId)) {
    throw new Error('Invalid document ID');
  }
  const doc = await db.collection('content').doc(params.docId).get();
  const data = doc.data();
  return view.render('doc', { content: escapeHtml(data?.content || '') });
});

4. Leverage AdonisJS context helpers. Use the built-in context escaping in Edge templates where possible, and prefer component-based rendering for dynamic sections:

{{/* profile.edge — rely on context-aware escaping */}}
<div>{{ bio }}</div>
{{/* If using components, isolate logic */}}

These practices ensure that Firestore data is treated as untrusted input and never directly drives template behavior, effectively mitigating SSTI risks in AdonisJS applications.

Frequently Asked Questions

Can Firestore itself be exploited via SSTI in AdonisJS?
No. SSTI is a template engine issue, not a Firestore vulnerability. Firestore supplies data; the risk arises when that data is rendered unsafely in AdonisJS templates.
Does middleBrick detect SSTI in AdonisJS applications that use Firestore?
middleBrick runs black-box scans against unauthenticated endpoints and can identify indicators of SSTI in rendered outputs and API behavior. It does not fix the issue but provides findings with remediation guidance to help you address unsafe template usage.