Directory Traversal
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.
- Resolve the full path.
- 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.
