Luke a Pro

Luke Sun

Developer & Marketer

šŸ‡ŗšŸ‡¦

Directory Traversal

| , 3 minutes reading.

1. Definition

Directory Traversal (or Path Traversal) aims to access files and directories that are stored outside the web root folder.

By manipulating variables that reference files with ā€œdot-dot-slashā€ (../) sequences and its variations, an attacker can access arbitrary files and directories stored on file system including application source code or configuration and critical system files.

2. Technical Explanation

If an application accepts a filename and appends it to a path without validation:

// Vulnerable Node.js
app.get('/download', (req, res) => {
  const filePath = path.join(__dirname, 'public', req.query.file);
  res.sendFile(filePath);
});

Normal Request: ?file=report.pdf -> /app/public/report.pdf

Attack Request: ?file=../../../../etc/passwd The filesystem resolves .. to the parent directory. Result: /app/public/../../../../etc/passwd -> /etc/passwd.

3. Attack Flow

sequenceDiagram
    participant Attacker
    participant App
    participant FS as FileSystem

    Attacker->>App: GET /image?filename=../../../etc/shadow
    
    Note over App: App joins path:<br/>"/var/www/html/images/" + "../../../etc/shadow"
    
    App->>FS: Read File
    Note over FS: Path resolves to /etc/shadow
    
    FS-->>App: Return File Content (Password Hashes)
    App-->>Attacker: 200 OK (Sensitive Data)

4. Real-World Case Study: Grafana (2021)

Target: Grafana (Dashboards). Vulnerability Class: Directory Traversal (CVE-2021-43798).

The Vulnerability: Grafana had a plugin asset loader that accepted a plugin ID and a file path. It did not properly sanitize the file path.

The Attack: Attackers could send a request like: /public/plugins/alertlist/../../../../../../../../etc/passwd

Because the application blindly trusted the path segment after the plugin name, it served any file on the host server. This was a Zero-Day exploit used in the wild to steal configuration files (containing database passwords) before many admins could patch.

5. Detailed Defense Strategies

A. Avoid User Input in File Paths

The most secure way is to not let users supply filenames at all.

  • Indirect Reference: Use an ID (1, 2, 3) mapped to a filename in the database.

B. Path Normalization & Prefix Check

If you must use user input, use the language’s native path canonicalization before using the path.

  1. Resolve the full path.
  2. Check that the resolved path starts with the expected directory.
// Secure Node.js
const safeDir = path.resolve(__dirname, 'public');
const userPath = path.resolve(safeDir, req.query.file);

if (!userPath.startsWith(safeDir)) {
  throw new Error('Access Denied!');
}
res.sendFile(userPath);

C. Chroot Jails

Run the web server process in a ā€œJailā€ or Container (Docker) that only sees a subset of the filesystem. Even if traversal succeeds, the attacker only sees the container’s isolated files, not the host’s /etc/passwd.

6. References