Server Side Template Injection in Hapi with Basic Auth
Server Side Template Injection in Hapi with Basic Auth — how this specific combination creates or exposes the vulnerability
Server Side Template Injection (SSTI) in Hapi becomes notably more risky when routes rely solely on HTTP Basic Authentication for access control. Hapi does not apply any template sandboxing by default, and if user-influenced data reaches a template helper or partial without validation, an attacker can break out of the intended rendering context. When Basic Auth protects a route, the presence of credentials may lead developers to assume the endpoint is internal or low-risk, which can reduce scrutiny on input handling and encourage unsafe template usage.
Consider a Hapi route that uses Basic Auth and passes unchecked user input into a template. The route handler might extract the username from the auth credentials and merge it into a template context. If the template uses string interpolation or unsafe includes, an attacker who knows the endpoint can inject template syntax that executes arbitrary logic. For example, if the application uses Handlebars, payloads like {{}} or {{#}} can be crafted to access global objects, invoke helpers, or trigger side effects. The Basic Auth header provides a stable way to repeatedly access the endpoint during reconnaissance, making it easier to iterate on injection patterns without being blocked by missing authentication.
During a black-box scan, middleBrick tests unauthenticated paths first, but when Basic Auth is required and credentials are discoverable (e.g., hardcoded examples or leaked configuration), the scanner can authenticate and probe authenticated surfaces. This means SSTI findings behind Basic Auth are still surfaced, with details on how credentials change the attack surface. The scanner checks whether template logic can be influenced by data derived from authentication context, such as user claims, roles, or identifiers passed into the render layer. Because Hapi does not enforce a strict separation between route authentication and template rendering, the boundary between trusted and untrusted data can blur, increasing the likelihood that an injected template expression can reach filesystem helpers, URL builders, or external service calls.
Real-world patterns observed in Hapi applications include passing request.auth.credentials directly into template data, concatenating user-controlled strings into partial names, or constructing includes based on route parameters. These patterns become exploitable when the template engine does not treat dynamic references as strictly data-only. An attacker may attempt to read server-side files, trigger SSRF through custom helpers, or escalate via prototype pollution depending on the engine and version. Because middleBrick runs multiple checks in parallel, it correlates the presence of Basic Auth with template rendering steps to highlight scenarios where authentication does not mitigate injection risks.
In practice, a safe posture requires validating and sanitizing any data entering the template context, regardless of authentication method. Do not rely on route-level auth mechanisms alone to prevent template logic manipulation. Use strict allowlists for partials and helpers, avoid direct interpolation of user-controlled strings, and prefer data-only contexts over executable expressions. middleBrick’s reporting maps these findings to the OWASP API Top 10 and provides remediation guidance tailored to Hapi and the underlying template engine, helping teams understand how to reduce the attack surface without changing the authentication model.
Basic Auth-Specific Remediation in Hapi — concrete code fixes
To reduce SSTI risk in Hapi when using Basic Auth, ensure that user-influenced values never reach the template engine unescaped or unchecked. Refactor route handlers to separate authentication data from template context, and apply strict validation before rendering. The following examples illustrate secure patterns.
Insecure example to avoid:
// BAD: directly injecting auth credentials into template context
server.route({
method: 'GET',
path: '/profile',
options: {
auth: {
strategy: 'basic',
scope: ['user']
},
handler: function (request, h) {
const user = request.auth.credentials;
return h.view('profile', {
username: user.username,
role: user.role,
// unsanitized values can reach the template
customData: request.query.input
});
}
}
});
Secure alternative:
// GOOD: strict allowlist, no raw user input in template context
const safeKeys = ['id', 'username', 'email', 'role'];
server.route({
method: 'GET',
path: '/profile',
options: {
auth: {
strategy: 'basic',
scope: ['user']
},
handler: function (request, h) {
const user = request.auth.credentials;
const safeContext = safeKeys.reduce((acc, key) => {
if (user && Object.prototype.hasOwnProperty.call(user, key)) {
acc[key] = user[key];
}
return acc;
}, {});
// sanitize any external data separately
const sanitizedInput = sanitize(request.query.input || '');
return h.view('profile', {
user: safeContext,
input: sanitizedInput
});
}
}
});
function sanitize(value) {
return String(value).replace(/[<>"'&]/g, (match) => ({
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
}[match]));
}
Additional recommendations:
- Do not use dynamic partial names derived from user or auth data. If includes are necessary, resolve them against a hardcoded allowlist.
- Apply context-aware escaping in the template engine and avoid disabling sandboxing for convenience.
- Use validation layers (e.g., Joi) on query parameters and payloads before they touch handlers or views.
- Prefer token-based or session-based auth for high-sensitivity endpoints, and reserve Basic Auth for low-risk, read-only routes where credentials are short-lived and scoped.
By combining disciplined context separation, input validation, and strict template usage policies, teams can retain Basic Auth while minimizing the impact of SSTI vectors. middleBrick can validate that these mitigations are reflected in runtime behavior, ensuring that authenticated routes do not inadvertently expose template injection surfaces.