Path Traversal in Hapi with Mutual Tls
Path Traversal in Hapi with Mutual Tls — how this specific combination creates or exposes the vulnerability
Path Traversal in Hapi with Mutual Transport Layer Security (Mutual TLS) involves a conflict between secure transport configuration and unsafe handling of user-supplied file paths. Hapi is a rich framework for building web applications and services in Node.js, and it supports TLS options for both incoming connections and outgoing requests. When Mutual TLS is enforced, the server authenticates clients via client certificates, and clients authenticate the server via a trusted CA. This setup ensures strong identity and encrypted communication, but it does not automatically prevent Path Traversal in application logic.
Path Traversal occurs when an endpoint constructs file system paths using unsanitized user input, allowing an attacker to navigate outside intended directories using sequences like ../. In a Hapi service with Mutual TLS, the server may assume that authenticated clients are trustworthy and therefore skip rigorous validation of request parameters. This assumption can lead to insecure direct object references or path concatenation patterns such as:
const Hapi = require('@hapi/hapi');
const init = async () => {
const server = Hapi.server({
port: 443,
tls: {
cert: '/path/to/server-cert.pem',
key: '/path/to/server-key.pem',
ca: '/path/to/ca.pem',
requestCert: true,
rejectUnauthorized: true
}
});
server.route({
method: 'GET',
path: '/files/{filename}',
handler: (request, h) => {
const filename = request.params.filename;
const path = `/var/www/uploads/${filename}`;
return require('fs').readFileSync(path, 'utf8');
}
});
await server.start();
};
Even with Mutual TLS, if the filename input is not validated, an authenticated client can request /files/../../../etc/passwd, causing the server to read sensitive files. The TLS layer secures the channel and verifies identities, but it does not sanitize or constrain path construction. Attack patterns like this align with the OWASP API Security Top 10 Path Traversal and can be discovered by scanners such as middleBrick, which tests unauthenticated attack surfaces and can flag insecure path handling even when Mutual TLS is in use.
Additionally, Hapi servers may use route configurations with custom validation rules. If validation only checks format (e.g., string pattern) and does not restrict directory traversal sequences, the vulnerability persists. The server’s TLS settings, including client certificate verification, operate at the transport layer and do not intersect with application-level path resolution. Therefore, developers must explicitly normalize and restrict file paths, use allowlists for permitted resources, and avoid direct filesystem access based on user input, regardless of Mutual TLS enforcement.
Mutual Tls-Specific Remediation in Hapi — concrete code fixes
To remediate Path Traversal in Hapi while using Mutual TLS, you must combine secure TLS configuration with strict input validation and safe path resolution. The following example demonstrates a hardened Hapi server that uses Mutual TLS and mitigates path traversal risks:
const Hapi = require('@hapi/hapi'); const path = require('path'); const fs = require('fs'); const init = async () => { const server = Hapi.server({ port: 443, tls: { cert: '/path/to/server-cert.pem', key: '/path/to/server-key.pem', ca: '/path/to/ca.pem', requestCert: true, rejectUnauthorized: true } }); server.route({ method: 'GET', path: '/files/{filename}', options: { validate: { params: { filename: require('@hapi/joi').string().alphanum().min(1).max(255) } } }, handler: (request, h) => { const filename = request.params.filename; // Use path.resolve and a base directory to prevent traversal const baseDir = '/var/www/uploads'; const safePath = path.resolve(baseDir, filename); // Ensure the resolved path is within the base directory if (!safePath.startsWith(baseDir)) { throw new Error('Forbidden'); } if (!fs.existsSync(safePath)) { throw new Error('Not found'); } return fs.readFileSync(safePath, 'utf8'); } }); await server.start(); };Key remediation practices include:
- Input validation with Joi: Restrict filenames to alphanumeric characters and limit length to prevent injection of path sequences.
- Path normalization: Use
path.resolveto eliminate..and.segments, then verify that the resolved path remains within the intended base directory. - Explicit allowlisting: Serve files only from a predefined directory and avoid dynamic paths that incorporate user input without checks.
- Transport security: Continue enforcing Mutual TLS with
requestCertandrejectUnauthorizedto ensure client authenticity, while recognizing that this does not replace application-level safeguards.
For developers using the middleBrick CLI, you can scan from terminal with middlebrick scan <url> to detect Path Traversal findings even in environments protected by Mutual TLS. Teams on the Pro plan can enable continuous monitoring and integrate the GitHub Action to fail builds if risk scores exceed thresholds, ensuring that path handling issues are caught before deployment.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |
Frequently Asked Questions
Does Mutual TLS prevent Path Traversal in Hapi endpoints?
How can I safely serve files from a directory in Hapi while using Mutual TLS?
path.resolve, and confirm that the resolved path remains inside a predefined base directory. Always treat user input as untrusted regardless of TLS settings.