What Is Path Traversal
Path traversal (also called directory traversal) is a vulnerability where an attacker manipulates file path input to access files outside the directory the application intends to serve. By including sequences like ../ (dot-dot-slash) in a filename parameter, the attacker navigates up the directory tree and reads arbitrary files — configuration files, source code, credentials, private keys, or system files.
Classified as CWE-22: Improper Limitation of a Pathname to a Restricted Directory and part of OWASP A01:2025 — Broken Access Control, path traversal appears in any application that constructs file paths from user-controlled input: file download endpoints, image serving, template loading, log viewing, and configuration retrieval.
The severity ranges from data exposure (reading configuration files, source code) to credential theft (reading .env files, private keys) to full server compromise (reading SSH keys, reading application source to find further vulnerabilities).
How ../ Sequences Escape the Intended Directory
When a server constructs a file path by concatenating a base directory with user input, ../ sequences traverse upward through the filesystem:
// Intended: serve files from /var/www/uploads/
const filePath = path.join('/var/www/uploads/', req.query.filename);
// User requests: filename=../../../etc/passwd
// Result: /var/www/uploads/../../../etc/passwd
// Resolved: /etc/passwd
Three ../ sequences escape three directory levels. The resolved path then points to /etc/passwd, exposing the system user database.
Encoding bypasses
Security filters that block ../ literally can often be bypassed with URL encoding or alternative representations:
%2e%2e%2f— URL-encoded../..%2f— mixed encoding%2e%2e/— partial encoding..— Windows backslash traversal
Effective prevention does not rely on filtering traversal sequences — it uses path canonicalization to resolve the final path and verifies it falls within the intended directory.
Real-World Path Traversal Breaches
- Cisco ASA (CVE-2020-3452): A path traversal in Cisco's Adaptive Security Appliance web services allowed unauthenticated attackers to read sensitive files including web session tokens. CVSS 7.5, affecting hundreds of thousands of devices.
- Pulse Secure VPN (CVE-2019-11510): An unauthenticated path traversal allowed attackers to read arbitrary files including cached plaintext credentials. Exploited widely in 2020 by ransomware groups and nation-state actors after proof-of-concept publication.
- Uber (2016): Path traversal in an internal admin tool exposed driver records and trip data. Combined with other vulnerabilities to exfiltrate 57 million records.
- GitLab (CVE-2023-2825): Path traversal in GitLab CE/EE allowed unauthenticated users to read arbitrary files on the server when an attachment was present in a public project. CVSS 10.0.
Path traversal vulnerabilities are particularly dangerous in VPNs, web gateways, and file management applications where reading internal files directly aids further attack planning.
Language-Specific Vulnerable Patterns
Node.js / TypeScript
Vulnerable:
// path.join does NOT prevent traversal
app.get('/files/:name', (req, res) => {
const filePath = path.join('/uploads', req.params.name);
res.sendFile(filePath);
});
// Attack: GET /files/../../etc/passwd
Secure:
app.get('/files/:name', (req, res) => {
const base = path.resolve('/uploads');
const filePath = path.resolve(base, req.params.name);
if (!filePath.startsWith(base + path.sep)) {
return res.status(403).send('Forbidden');
}
res.sendFile(filePath);
});
Python
Vulnerable:
from flask import request, send_file
import os
@app.route('/download')
def download():
filename = request.args.get('file')
return send_file(os.path.join('/uploads', filename))
# Attack: file=../../etc/passwd
Secure:
import os
@app.route('/download')
def download():
filename = request.args.get('file')
base = os.path.realpath('/uploads')
full_path = os.path.realpath(os.path.join(base, filename))
if not full_path.startswith(base + os.sep):
abort(403)
return send_file(full_path)
Java
Vulnerable:
// VULNERABLE: No canonicalization
String filename = request.getParameter("file");
File file = new File("/uploads/" + filename);
FileInputStream fis = new FileInputStream(file);
Secure:
// SECURE: Canonical path validation
String filename = request.getParameter("file");
File base = new File("/uploads").getCanonicalFile();
File file = new File(base, filename).getCanonicalFile();
if (!file.getPath().startsWith(base.getPath() + File.separator)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
Go
Vulnerable:
// VULNERABLE: filepath.Join does not prevent traversal
filename := r.URL.Query().Get("file")
filePath := filepath.Join("/uploads", filename)
http.ServeFile(w, r, filePath)
Secure:
// SECURE: Clean and validate
import "strings"
filename := r.URL.Query().Get("file")
base := filepath.Clean("/uploads")
filePath := filepath.Clean(filepath.Join(base, filename))
if !strings.HasPrefix(filePath, base+string(filepath.Separator)) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
http.ServeFile(w, r, filePath)How CodeSlick Detects Path Traversal (CWE-22)
CodeSlick identifies path traversal patterns across JavaScript, TypeScript, Python, Java, and Go by detecting file operations using user-controlled input without canonical path validation:
- JavaScript/TypeScript:
fs.readFile(),fs.createReadStream(),res.sendFile(),path.join()with request parameters without a subsequentpath.resolve()+ prefix check - Python:
open(),send_file(),os.path.join()withrequest.argsorrequest.formvalues withoutos.path.realpath()validation - Java:
new File(userInput),FileInputStream,Files.readAllBytes()withoutgetCanonicalFile()validation - Go:
os.Open(),os.ReadFile(),http.ServeFile()with query/form values withoutfilepath.Clean()and prefix validation
Findings are mapped to CWE-22 with CVSS severity 7.5 (High) and OWASP A01:2025 classification. AI-powered fix suggestions generate the canonical path validation pattern specific to your language and framework.
Detect path traversal vulnerabilities (CWE-22) across JavaScript, TypeScript, Python, Java, and Go in under 3 seconds.