HIGH path traversalexpress

Path Traversal in Express

How Path Traversal Manifests in Express

Path traversal vulnerabilities in Express applications typically arise from unsafe file operations where user input is used to construct filesystem paths without proper validation. The most common scenario involves using req.params, req.query, or req.body directly in fs operations.

Consider this vulnerable Express route:

app.get('/download/:filename', (req, res) => {
  const filePath = `/var/www/files/${req.params.filename}`;
  res.download(filePath);
});

An attacker can request /download/../../../etc/passwd to traverse outside the intended directory. Express's res.download() doesn't automatically sanitize paths, so the .. sequences are resolved by the underlying filesystem.

Another common pattern involves dynamic template rendering:

app.get('/view/:page', (req, res) => {
  const page = req.params.page;
  res.render(`pages/${page}`);
});

This allows attackers to access any template file on the server by manipulating the page parameter.

Static file serving can also be vulnerable if not properly configured:

app.use('/static', express.static('/var/www'));
app.use('/download', express.static('/var/www'));

Without proper path restrictions, an attacker might access /static/../../etc/passwd or similar paths.

Express middleware like multer for file uploads can introduce traversal risks:

const upload = multer({ dest: '/uploads/' });
app.post('/upload', upload.single('file'), (req, res) => {
  // Attacker could manipulate filename to overwrite critical files
});

The key issue is that Express provides powerful file system operations but doesn't enforce path safety by default, leaving developers responsible for proper input validation and path sanitization.

Express-Specific Detection

Detecting path traversal in Express applications requires both static code analysis and dynamic testing. For static analysis, look for these Express-specific patterns:

const vulnerablePatterns = [
  /res\.download\s*\(\s*[^)]*req\./,
  /fs\.(readFile|readdir|writeFile|mkdir)\s*\(\s*[^)]*req\./,
  /res\.render\s*\(\s*[^)]*req\./,
  /express\.static\s*\(\s*[^)]*req\./
];

Dynamic testing with middleBrick specifically targets Express applications by:

  • Scanning for unauthenticated endpoints that accept path parameters
  • Testing ../ sequences in file-related parameters
  • Verifying if res.download() properly restricts file access
  • Checking template rendering paths for traversal
  • Testing static file serving configurations

middleBrick's Express-specific detection includes testing for common traversal payloads:

../
..\ 
/\..\
..%2F..
..%5C..
..%c0%af..
..%c1%9c..
....//
....\\

The scanner also verifies if applications properly handle encoded traversal sequences and mixed forward/backward slashes. For applications using multer or similar middleware, middleBrick tests for upload path manipulation vulnerabilities.

middleBrick's API security scanning provides a security score (A–F) with specific findings for path traversal vulnerabilities, including severity levels and remediation guidance. The scanner tests the unauthenticated attack surface in just 5–15 seconds without requiring credentials or configuration.

Express-Specific Remediation

Express provides several built-in mechanisms to prevent path traversal vulnerabilities. The most effective approach is using path.join() with a fixed base directory:

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

app.get('/download/:filename', (req, res) => {
  const safeBase = path.join(__dirname, 'public', 'files');
  const requestedFile = path.basename(req.params.filename);
  const filePath = path.join(safeBase, requestedFile);
  
  // Verify the resolved path is within the safe base
  if (!filePath.startsWith(safeBase)) {
    return res.status(400).json({ error: 'Invalid file path' });
  }
  
  if (!fs.existsSync(filePath)) {
    return res.status(404).json({ error: 'File not found' });
  }
  
  res.download(filePath);
});

For template rendering, use a whitelist approach:

const allowedPages = new Set(['home', 'about', 'contact']);

app.get('/view/:page', (req, res) => {
  const page = req.params.page;
  
  if (!allowedPages.has(page)) {
    return res.status(400).json({ error: 'Invalid page' });
  }
  
  res.render(`pages/${page}`);
});

Static file serving should use the dotfiles option:

app.use('/static', express.static('/var/www', {
  dotfiles: 'deny',
  index: false
}));

For file uploads with multer, sanitize filenames:

const sanitize = require('sanitize-filename');

const upload = multer({
  dest: '/uploads/',
  fileFilter: (req, file, cb) => {
    const safeName = sanitize(file.originalname);
    if (safeName !== file.originalname) {
      return cb(new Error('Invalid filename'), false);
    }
    cb(null, true);
  }
});

Consider using the express-sanitizer middleware for additional input validation:

const sanitizer = require('express-sanitizer');
app.use(sanitizer());

Regular security scanning with middleBrick helps identify path traversal vulnerabilities before attackers can exploit them. The scanner tests your Express endpoints against known traversal payloads and provides specific remediation guidance for each finding.

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

How does middleBrick detect path traversal in Express applications?
middleBrick performs black-box scanning of your Express API endpoints, testing for path traversal by sending payloads with ../ sequences, encoded traversal attempts, and mixed slash patterns to file-related parameters. It specifically tests res.download(), res.render(), and static file serving configurations. The scanner runs in 5–15 seconds without requiring credentials and provides a security score with severity levels and remediation guidance.
Can path traversal vulnerabilities be exploited through JSON body parameters in Express?
Yes, if your Express route accepts JSON with file paths and uses them in filesystem operations without validation. For example, a POST endpoint that reads a file path from req.body and passes it to fs.readFile() is vulnerable. Always validate and sanitize any user-supplied path, regardless of whether it comes from query parameters, route params, or JSON bodies. Use path.basename() and verify the resolved path stays within your intended directory.