HIGH server side template injectionadonisjsapi keys

Server Side Template Injection in Adonisjs with Api Keys

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

Server Side Template Injection (SSTI) in AdonisJS becomes particularly risky when API keys are used to control template rendering, evaluate expressions, or dynamically generate content. SSTI occurs when an attacker can inject template code that is later interpreted by the server-side rendering engine. In AdonisJS, this often involves the built-in Edge.js view engine or custom template utilities used to render dynamic responses.

When API keys are embedded into templates—either as variables or used to gate rendering logic—they can become controllable input if derived from user-supplied data. For example, if a route uses an API key from a header or query parameter and passes it directly into an Edge template context, an attacker may manipulate the key to inject template syntax. A payload such as {{\u003c%_ include("partials/" + key) %\u003e}} or {{this[key]}} can lead to arbitrary code execution or sensitive data exposure when the template engine evaluates the injected expression.

AdonisJS applications that use API keys for feature flags, tenant identification, or scoped data access may inadvertently expose these keys or related logic through SSTI. For instance, if a template conditionally includes modules based on the API key value, an attacker can probe for internal file paths or module names using payloads like {{foo.constructor.constructor("return process")()}}. This exposes runtime environment details and may facilitate further attacks. Because API keys are often treated as trusted values, developers may skip input validation or context-aware escaping, increasing the risk of injection.

The combination of SSTI and API keys also amplifies data exposure. If a compromised template can access process environment variables or configuration objects keyed by the API key, sensitive credentials or internal endpoints may be leaked. In an unauthenticated scan scenario, middleBrick tests for such injection vectors by probing template contexts with payloads designed to execute code or read files, highlighting places where API keys flow into rendering logic without proper sanitization or sandboxing.

To detect these issues, security scans analyze how API keys enter the request lifecycle and whether they influence template rendering paths. Findings typically include unsafe variable interpolation, missing output encoding, and overly permissive template contexts. Remediation involves strict input validation, avoiding dynamic template inclusion or evaluation based on API key values, and enforcing least privilege in template data models.

Api Keys-Specific Remediation in Adonisjs — concrete code fixes

To mitigate SSTI when using API keys in AdonisJS, ensure API key values are never directly interpolated into templates or used to control template logic. Instead, treat API keys as opaque identifiers and validate them against a known set before use.

1. Use constant, pre-defined configuration for template selection rather than dynamic values derived from API keys. For example, map an allowed set of tenant identifiers to template names:

// config/tenants.js
module.exports = {
  mappings: {
    'ak_live_abc123': 'tenant_alpha',
    'ak_live_def456': 'tenant_beta'
  }
}

// In a controller
const tenants = use('Config').get('tenants.mappings')
const templateName = tenants[apiKey]
if (!templateName) {
  throw new Error('Unauthorized API key')
}
return View.render(templateName, { data })

2. If you must use API keys for data scoping, pass them as opaque parameters to services that handle data retrieval—not to the template context. Keep the template context minimal and free of executable logic:

// services/ReportService.js
class ReportService {
  async generate({ tenantKey, userId }) {
    const tenant = await Tenant.findByOrFail('api_key', tenantKey)
    return Report.query().where('tenant_id', tenant.id).fetch()
  }
}

// In a controller
const reports = await ReportService.generate({ tenantKey: apiKey, userId })
return View.render('reports/dashboard', { reports })

3. Avoid using user-influenced values in Edge template includes or dynamic expressions. If you must include partials, use a strict allowlist:

// Safe partial resolver
const allowedPartials = ['header', 'footer', 'card']
const partialName = allowedPartials.includes(requested) ? requested : 'header'
return View.render('main', { partial: partialName })

4. Enforce input validation on any parameter that could influence template rendering. Use AdonisJS schema validation to reject unexpected or malformed API keys before they reach the view layer:

const schema = use('Validator').create({
  api_key: 'string|required|regex:^ak_live_[a-z0-9]+$'
})

if (!(await schema.validate(request.all()))) {
  return response.badRequest(schema.messages())
}

These patterns reduce the attack surface by ensuring API keys do not directly influence template logic or content assembly, thereby preventing SSTI vectors that rely on injected template code.

Frequently Asked Questions

Can SSTI in AdonisJS lead to remote code execution if API keys are exposed in templates?
Yes. If an API key influences template rendering and is itself controllable, attackers can inject template syntax that executes code, leading to remote code execution or data exfiltration.
Does middleBrick detect SSTI in AdonisJS applications that use API keys?
middleBrick tests unauthenticated attack surfaces and can identify SSTI indicators such as unsafe variable interpolation and dynamic template inclusion, including scenarios where API keys affect template context.