Path Traversal in Vibe Coded Apps
How attackers escape your directories to read sensitive files like .env and /etc/passwd
Path traversal happens when attackers use ../ sequences to escape your intended directory and read files like your .env file. AI tools generate vulnerable file handling code. Always validate that resolved paths stay within allowed directories.
Source: OWASP Top 10 (2021) - Path traversal is part of Broken Access Control
What is path traversal?
Path traversal (also called directory traversal) is a vulnerability where attackers use ../ sequences to escape your intended directory and access files elsewhere on the server.
When your code uses user input to construct file paths without validation, attackers can read sensitive files like /etc/passwd, configuration files, or your .env file containing API keys.
Think of it like an elevator that should only go to floors 1-10, but hackers trick it into going to the basement where secrets are stored by pressing "-1" repeatedly.
According to OWASP Top 10 (2021), path traversal falls under Broken Access Control, ranked #1. CWE-22 is in the CWE Top 25 Most Dangerous Software Weaknesses. The PortSwigger Path Traversal Guide provides detailed exploitation and prevention techniques. For vibe coders building file upload or download features, this is critical because AI tools generate vulnerable patterns by default.
How do AI tools cause path traversal?
AI tools generate path traversal vulnerabilities by creating simple, functional file handling code that concatenates user input directly into file paths. When you ask for a "file download endpoint" or "file upload feature," AI prioritizes working code over secure code.
Dangerous pattern: AI-generated file download
When you ask AI for a file download feature, it often generates this:
// VULNERABLE: AI generates this for "download file" feature
app.get('/download', (req, res) => {
const filename = req.query.file
const filepath = `./uploads/${filename}` // DANGEROUS!
res.sendFile(filepath)
})
// Attacker uses: /download?file=../../../etc/passwd
// Result: Server sends /etc/passwd to attackerThis code works for legitimate users, which is why AI generates it. But it allows attackers to escape the uploads directory using ../ sequences.
The false sense of security: Many vibe coders add path.resolve() thinking it prevents traversal. It doesn't. path.resolve() normalizes the path but doesn't restrict it. You must verify the result stays within your allowed directory.
Common vulnerable features in vibe coded apps include file downloads, image uploads, user avatar handling, document exports, and any endpoint that takes a filename parameter. Tools like Cursor, Bolt, and Claude Code can all generate these patterns.
What attack patterns do hackers use?
Attackers use various encoding and sequence techniques to bypass weak filters. Simply removing ../ from input is not sufficient.
Basic traversal
../../../etc/passwd Simple sequence that works when there's no filtering at all.
URL encoded
%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd Bypasses filters that check for literal ../ but don't decode first.
Double encoding
%252e%252e%252f Bypasses filters that decode once. Gets decoded twice by the server.
Windows backslash
..\..\..\windows\system32\config\sam Windows accepts both / and \ as separators.
Filter bypass
....//....//....//etc/passwd If filter removes ../ once, this becomes ../../../etc/passwd.
According to PortSwigger, these bypass techniques are commonly successful because developers implement incomplete fixes.
What could happen if I have path traversal?
Path traversal can lead to sensitive file exposure, configuration theft, source code leaks, and in some cases remote code execution.
- Secrets exposure: Attackers read your
.envfile containing API keys, database credentials, and JWT secrets - see hardcoded secrets - Configuration theft: Access to
/etc/passwd, database configs, cloud credentials - Source code leak: Reading your application code exposes business logic and other vulnerabilities
- Data destruction: If combined with write access, attackers can overwrite or delete files
- Code execution: Overwriting executable files or configs can lead to server compromise
How do I detect path traversal?
Search for file path construction that uses user input. Any code that builds paths from request parameters is potentially vulnerable.
// User input in file paths (DANGEROUS)
const filepath = `./uploads/${req.query.file}`
const filepath = path.join(uploadDir, filename)
const filepath = uploadDir + '/' + userInput
// File operations with user input (DANGEROUS)
res.sendFile(filepath)
fs.readFile(filepath)
fs.writeFile(filepath, data)
fs.createReadStream(filepath)
// path.resolve WITHOUT validation (STILL DANGEROUS)
const filepath = path.resolve('./uploads', filename)
res.sendFile(filepath) // No check if it's still in uploads!
// Regex to find vulnerable patterns:
// (sendFile|readFile|writeFile|createReadStream)\s*\([^)]*\$\{
// path\.(join|resolve)\s*\([^)]*req\.(query|params|body)Don't want to search manually?
Scan your code freeHow do I fix path traversal?
Fix path traversal by validating that the resolved path stays within your allowed directory. Use path.resolve() to get the absolute path, then check it starts with your base directory.
AI Fix Prompt
Copy this prompt into Cursor, Claude Code, or Bolt to automatically fix path traversal in your codebase:
Manual Fix
The fix is: resolve the path, then verify it's still inside your allowed directory. Never trust user-supplied filenames.
// path.resolve alone is NOT enough!
const path = require('path')
app.get('/download', (req, res) => {
const filename = req.query.file
const filepath = path.resolve('./uploads', filename)
res.sendFile(filepath) // STILL DANGEROUS!
})
// Attacker inputs: ../../../etc/passwd
// path.resolve returns: /etc/passwd
// File is served - attack succeeds!// Validate resolved path stays in allowed directory
const path = require('path')
const UPLOADS_DIR = path.resolve('./uploads')
app.get('/download', (req, res) => {
const filename = req.query.file
const filepath = path.resolve(UPLOADS_DIR, filename)
// CRITICAL: Check path is within uploads
if (!filepath.startsWith(UPLOADS_DIR + path.sep)) {
return res.status(403).send('Access denied')
}
res.sendFile(filepath)
})
// Attacker inputs: ../../../etc/passwd
// filepath resolves to: /etc/passwd
// Check fails: /etc/passwd doesn't start with /uploads/
// Returns 403 - attack blocked!Why + path.sep? Without the separator, /uploads-evil/file.txt would pass the check because it starts with /uploads.
Adding the separator ensures only paths inside the directory are allowed.
Frequently asked questions
What is path traversal vulnerability?
Path traversal (also called directory traversal or CWE-22) is a vulnerability where attackers use special character sequences like ../ to escape the intended directory and access files elsewhere on the server. This can expose sensitive files like /etc/passwd, configuration files, or your .env file containing secrets.
How do I prevent path traversal in Node.js?
Use path.resolve() to get the absolute path, then verify it starts with your allowed base directory plus the path separator. For example: if (!filepath.startsWith(UPLOADS_DIR + path.sep)) return error. Never trust user-supplied filenames without validation.
What is the difference between path traversal and LFI?
Path traversal is the technique of using ../ sequences to navigate directories. LFI (Local File Inclusion) is an attack that uses path traversal to include local files in application output, often to execute code or read sensitive data. LFI is essentially path traversal exploited in include/require functions.
Can path traversal lead to remote code execution?
Yes. If attackers can traverse to writable directories, they may upload malicious files then access them. They might also overwrite configuration files, access log files for log poisoning attacks, or read source code to find other vulnerabilities. The risk depends on what files are accessible.
How do I test for path traversal vulnerabilities?
Test by sending ../ sequences in any parameter that handles file paths: upload filenames, download parameters, image sources. Try URL encoding (%2e%2e%2f), double encoding (%252e%252e%252f), and backslashes on Windows. Tools like Burp Suite can automate this testing.
Related content
Scan your code for path traversal
Check your codebase for path traversal and other file handling vulnerabilities in AI-generated code.
Try Vibeship Scanner