HIGH path traversalloopbackmutual tls

Path Traversal in Loopback with Mutual Tls

Path Traversal in Loopback with Mutual Tls

Path Traversal occurs when user-controlled input is used to construct file system paths without proper validation, enabling an attacker to access files outside the intended directory. In a Loopback application protected by Mutual Transport Layer Security (Mutual TLS), the presence of mTLS can create a false sense of security while the application remains vulnerable to Path Traversal if request parameters are mishandled.

Mutual TLS authenticates the client by requiring a client certificate. Once the TLS handshake succeeds, the application may assume the request is from a trusted source and process inputs more permissively. For example, an endpoint like /files/:filename might use the parameter directly to read from a directory:

const path = require('path');
const fs = require('fs');

app.get('/files/:filename', (req, res) => {
  const base = '/safe/directory';
  const filename = req.params.filename;
  const filePath = path.join(base, filename);
  fs.readFile(filePath, (err, data) => {
    if (err) return res.status(404).send('Not found');
    res.send(data);
  });
});

Even with mTLS in place, if filename is not validated, an attacker can supply values such as ../../../etc/passwd to traverse directories. The mTLS layer does not sanitize or restrict path components; it only confirms identity. Therefore, the combination of mTLS and Path Traversal leads to a scenario where authenticated (via client cert) requests can still read arbitrary files if path construction is insecure.

Additionally, if the Loopback application exposes an OpenAPI spec that documents user-controlled path parameters without indicating they must be restricted, automated scanners and developers might overlook the risk. The TLS layer ensures confidentiality and integrity of the transport, but it does nothing to validate that the resolved file path remains within the intended directory scope.

To align with findings from a middleBrick scan, which checks Input Validation and Data Exposure in parallel, developers should treat mTLS as an identity guarantee, not a content safety mechanism. Path Traversal findings from such scans typically include references to CWE-22 and OWASP API Top 10 Broken Object Level Authorization (BOLA) when paths expose sensitive resources.

Mutual Tls-Specific Remediation in Loopback

Remediation focuses on ensuring that user input never directly influences the file system path. Below are concrete code fixes for a Loopback application using Mutual TLS.

1. Use a strict allowlist for filenames

Instead of concatenating user input, validate against a known set of files:

const allowedFiles = new Set(['report.pdf', 'terms.pdf', 'invoice.json']);

app.get('/files/:filename', (req, res) => {
  const filename = req.params.filename;
  if (!allowedFiles.has(filename)) {
    return res.status(403).send('Forbidden');
  }
  const base = '/safe/directory';
  const filePath = path.join(base, filename);
  fs.readFile(filePath, (err, data) => {
    if (err) return res.status(404).send('Not found');
    res.send(data);
  });
});

2. Normalize and confine paths with path.resolve and prefix checks

Ensure the resolved path starts with the intended base directory:

app.get('/files/:filename', (req, res) => {
  const base = path.resolve('/safe/directory');
  const unsafe = path.resolve(base, req.params.filename);
  if (!unsafe.startsWith(base + path.sep) && unsafe !== base) {
    return res.status(403).send('Forbidden');
  }
  fs.readFile(unsafe, (err, data) => {
    if (err) return res.status(404).send('Not found');
    res.send(data);
  });
});

3. Mutual TLS in Loopback example with custom request interceptor

Configure the Loopback application to require client certificates and inspect them if needed:

const https = require('https');
const fs = require('fs');
const loopback = require('loopback');
const app = loopback();

const server = https.createServer({
  cert: fs.readFileSync('/path/to/server-cert.pem'),
  key: fs.readFileSync('/path/to/server-key.pem'),
  ca: [fs.readFileSync('/path/to/ca-cert.pem')],
  requestCert: true,
  rejectUnauthorized: true,
}, app);

server.listen(3000, () => {
  console.log('Loopback app with Mutual TLS listening on port 3000');
});

4. Combine path confinement with mTLS-aware logging

Log suspicious path attempts even when mTLS client certs are valid, to aid in detection:

app.get('/files/:filename', (req, res, next) =>
  req.accessToken || req.clientCertificate ? next() : res.status(401).send('Unauthorized'),
);

// After authorization, apply path checks as shown earlier

These measures ensure that even with Mutual TLS protecting the channel, the application does not inadvertently expose files outside its designated scope.

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?
No. Mutual TLS authenticates the client but does not validate or sanitize file path inputs. Path Traversal must be addressed through input validation and path confinement.
How can middleBrick help detect this issue?
middleBrick scans unauthenticated attack surfaces and includes Input Validation and Data Exposure checks that can identify Path Traversal risks in Loopback endpoints, even when Mutual TLS is in use.