Path Traversal Vulnerability Examples — Python, Node.js
Path traversal (directory traversal) vulnerabilities let attackers read files outside the intended directory using ../ sequences. This guide shows real examples in Python and Node.js — the vulnerable pattern, how attackers exploit it, and the correct fix.
What is path traversal?
A path traversal vulnerability exists when an application uses user-controlled input to build a file path without validating that the resulting path stays within the intended directory. An attacker sends a filename like ../../etc/passwd to escape the uploads folder and read any file the server process can access.
Impact: Attackers can read application source code, configuration files, private keys, database credentials, and system files. OWASP ranks it A01 (Broken Access Control).
Python Flask — Path Traversal
Web frameworks that serve user-requested files are the most common vector.
❌ Attacker can read any file
@app.route('/download')
def download():
filename = request.args.get('file')
file_path = f"/var/app/uploads/{filename}"
return send_file(file_path)
# Attack: GET /download?file=../../etc/passwd
# Returns: root:x:0:0:root:/root:/bin/bash ...✅ Realpath + directory check
import os
from flask import abort
UPLOAD_DIR = os.path.realpath("/var/app/uploads")
@app.route('/download')
def download():
filename = request.args.get('file', '')
# Resolve ALL ../ and symlinks to absolute path
safe_path = os.path.realpath(os.path.join(UPLOAD_DIR, filename))
# Verify it's still inside the uploads directory
if not safe_path.startswith(UPLOAD_DIR + os.sep):
abort(403) # Forbidden
return send_file(safe_path)Node.js Express — Path Traversal
Express file serving endpoints are vulnerable when using path.join with user input directly.
❌ Directory traversal in Express
app.get('/file', (req, res) => {
const filename = req.query.name;
const filePath = path.join(__dirname, 'uploads', filename);
res.sendFile(filePath);
// Attack: ?name=../../.env → exposes all env vars
// path.join normalizes but does NOT prevent traversal✅ path.resolve + startsWith check
const UPLOAD_DIR = path.resolve(__dirname, 'uploads');
app.get('/file', (req, res) => {
const filename = req.query.name;
const filePath = path.resolve(UPLOAD_DIR, filename);
// Verify path stays within UPLOAD_DIR
if (!filePath.startsWith(UPLOAD_DIR + path.sep)) {
return res.status(403).send('Forbidden');
}
res.sendFile(filePath);
});Python — File Upload Traversal
File uploads where the filename comes from the client are particularly dangerous.
❌ Using client filename directly
@app.route('/upload', methods=['POST'])
def upload():
file = request.files['document']
# Attacker sends filename: "../../app/config.py"
file.save(os.path.join('/uploads', file.filename))
# Overwrites application source code!✅ werkzeug.utils.secure_filename
from werkzeug.utils import secure_filename
import uuid
@app.route('/upload', methods=['POST'])
def upload():
file = request.files['document']
# secure_filename strips all path components and dangerous chars
safe_name = secure_filename(file.filename)
if not safe_name: # Empty after sanitization
return "Invalid filename", 400
# Use UUID to prevent filename conflicts and enumeration
unique_name = f"{uuid.uuid4()}_{safe_name}"
file.save(os.path.join('/uploads', unique_name))Pro tip: The safe pattern is always the same: os.path.realpath() (Python) or path.resolve() (Node.js) resolves all ../ sequences, then check that the result starts with your intended directory. Never trust client-provided filenames.
Detect Path Traversal in Your Code
Paste your code — LearnCodeGuide detects all these issues automatically using GPT-4o + Claude Sonnet. Free to start.
Analyze Your Code →Related Guides
Published by LearnCodeGuide Team · Last reviewed: November 2025