HIGH path traversalhapimutual tls

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.resolve to 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 requestCert and rejectUnauthorized to 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 IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Does Mutual TLS prevent Path Traversal in Hapi endpoints?
No. Mutual TLS secures transport and client authentication but does not validate or sanitize file path inputs. Application-level path handling must still enforce strict validation and safe resolution.
How can I safely serve files from a directory in Hapi while using Mutual TLS?
Use input validation (e.g., Joi) to restrict filename characters, resolve paths with path.resolve, and confirm that the resolved path remains inside a predefined base directory. Always treat user input as untrusted regardless of TLS settings.