Injection Attacks: SQL, Command, and LDAPLesson 2.4
Path traversal attacks: how attackers escape your intended directory
path traversal mechanics, ../ sequences, URL decoding bypass, path.resolve and path.join, realpath validation, allowlist of accessible paths
Path Traversal
Path traversal lets attackers read files outside your intended directory by injecting ../ sequences into a filename parameter. A successful attack can expose /etc/passwd, source code, private keys, or environment files.
The Vulnerable Pattern
// VULNERABLE
const filePath = path.join(__dirname, 'uploads', req.query.file);
// req.query.file = '../../etc/passwd'
// Resolved: /app/uploads/../../etc/passwd → /etc/passwd
res.sendFile(filePath);The Fix: Validate the Resolved Path
const path = require('path');
const fs = require('fs');
const BASE_DIR = path.resolve(__dirname, 'uploads');
app.get('/file', (req, res) => {
const requested = path.resolve(BASE_DIR, req.query.file);
// Ensure the resolved path is still inside BASE_DIR
if (!requested.startsWith(BASE_DIR + path.sep)) {
return res.status(403).json({ error: 'Access denied' });
}
if (!fs.existsSync(requested)) {
return res.status(404).json({ error: 'File not found' });
}
res.sendFile(requested);
});URL Encoding Bypass
Attackers also encode traversal sequences: %2e%2e%2f decodes to ../. Using path.resolve handles this automatically because Node's path module resolves the logical path before the startsWith check. Do not manually strip ../ from strings—it's easy to get wrong with double encoding like %252e%252e%252f.
