flawopen.com/path-traversal/Javascript

● CWE-918 · Hoch
Sicherheitsforschung · FlawOpen

Path Traversal in JavaScript

How naive path.join allows directory traversal in Express/Node.js, and how to enforce directory boundary checks with path.resolve and path.sep.

💡 Einfache Erklärung (ELI5)

Stellen Sie sich ein Hotelschloss vor, das eigentlich nur Zimmer im zweiten Stock öffnen soll. Wenn ein Gast am Tastenfeld '../../master-safe' eingibt, verlässt das Schloss den Flur und öffnet den Haupttresor des Hotelmanagers.

Kernkonzepte & Begriffe

Web Application Security
Kernkomponente der Architektur, die von CWE-918 betroffen ist.
CWE-918
Standardmäßige Common Weakness Enumeration (CWE)-Klassifizierung für path-traversal-javascript.
Defense-in-Depth
Mehrschichtige technische Verifikation und Laufzeit-Grenzenisolation.

Schritt-für-Schritt Angriffsablauf

Step 1

Eingabe des Client-Dateipfads

Ein Endpunkt akzeptiert Dateinamen oder Ressourcenbezeichner direkt über einen HTTP-Anfrageparameter.

Step 2

Injektion von Verzeichnis-Traversierungssequenzen

Der Angreifer schleust relative Pfadsequenzen wie '../', '..%2f' oder absolute Pfadüberschreibungen ein.

Step 3

Umgehung der Verzeichnisgrenze

Das Backend verbindet die Eingabe mit dem Basispfad, ohne kanonische Pfade aufzulösen oder Grenzen zu prüfen.

Step 4

Unbefugtes Lesen oder Überschreiben von Dateien

Das System öffnet und übermittelt vertrauliche Systemdateien (z. B. /etc/passwd oder Konfigurationsgeheimnisse).

Quellcode: Verwundbar vs. Sicher

✕ VERWUNDBARE IMPLEMENTIERUNG
// VULNERABLE: path.join allows directory breakout
const express = require('express');
const path = require('path');
const fs = require('fs');

const app = express();
const PUBLIC_DIR = path.join(__dirname, 'public');

app.get('/download', (req, res) => {
  // Attacker input: "../../etc/passwd"
  const targetFile = path.join(PUBLIC_DIR, req.query.file);
  
  // Directly pipes arbitrary system file to response!
  res.sendFile(targetFile);
});
✓ GEHÄRTETER SICHERHEITS-PATCH
// HARDENED: Canonicalize path and assert prefix with directory separator
const express = require('express');
const path = require('path');
const fs = require('fs');

const app = express();
const PUBLIC_DIR = path.resolve(__dirname, 'public');

app.get('/download', (req, res) => {
  const userInput = req.query.file;
  if (!userInput || typeof userInput !== 'string') {
    return res.status(400).send('Invalid file parameter');
  }

  // 1. Resolve to absolute path
  const safePath = path.resolve(PUBLIC_DIR, userInput);

  // 2. Strict boundary check: must start with base folder + separator
  if (!safePath.startsWith(PUBLIC_DIR + path.sep)) {
    return res.status(403).send('Forbidden: Path Traversal detected');
  }

  // 3. Verify file exists and is a regular file
  fs.stat(safePath, (err, stats) => {
    if (err || !stats.isFile()) return res.status(404).send('File not found');
    res.sendFile(safePath);
  });
});

Checkliste für Engineering & Systemsicherheit

References