CWE-22: Path Traversal
Overview
Path Traversal (Directory Traversal) occurs when an application uses user-supplied input to construct file paths without proper validation, allowing attackers to access files outside the intended directory.
OWASP Classification
A01:2025 - Broken Access Control
Risk
High: Can lead to unauthorized file access, source code disclosure, credential theft, or remote code execution if combined with file upload.
Relationship to Other CWEs
CWE-22 vs CWE-73 vs CWE-35:
- CWE-22 (This page): Focuses specifically on path traversal sequences (
../,..\) that allow escaping intended directories. Use this guidance when findings mention "directory traversal" or "dot-dot-slash".
- CWE-73 (External Control of File Name or Path): Broader category covering any user control over file paths, including both traversal attacks AND choosing arbitrary files within allowed directories. If your scan finding is CWE-73, check if it involves traversal sequences (also apply CWE-22 guidance) or just file selection.
- CWE-35 (Path Equivalence): Focuses on equivalent representations of the same path (
/pathvs/path/vs//path) bypassing validation. Less common in findings; mainly relevant if your validation uses string comparison without canonicalization.
Remediation overlap: All three benefit from canonicalization and allowlisting. CWE-22 and CWE-73 share most remediation steps.
Common Attack Patterns
../../../etc/passwd(Unix/Linux)..\..\..\..\windows\system32\config\sam(Windows)- URL encoding:
%2e%2e%2f,%2e%2e\ - Double encoding:
%252e%252e%252f - Absolute paths:
/etc/passwd,C:\windows\system.ini
Remediation Steps
Core principle: Never allow untrusted input to directly control filesystem paths; canonicalize and enforce containment within an allowlisted root.
Trace the Data Path
Analyze how untrusted data reaches file operations:
- Source: Identify where file path data enters (user input, external files, databases, network requests)
- Path Construction: Look for string concatenation with
/or\ - Sink: Locate file operation (
open(),File(),readFile(), etc.) - Missing Validation: Check for canonicalization or containment checks
Use Indirect References (Primary Defense)
Never use untrusted data directly as file paths. Use indirect references:
- Map to internal IDs: User provides ID/name, system maps to actual path
- Lookup from allowlist/database: Maintain allowed files in database
- Hide real paths: Users never see or control actual file paths
- Example: User requests
report_id=123, system maps to/var/reports/2024/report_123.pdf
Why this works: Users cannot manipulate paths they never see or control.
Validate Against Allowlist
If direct file references are unavoidable:
- Define allowed files/directories: Maintain explicit list of permitted paths
- Exact matching: Exact matching for file identifiers or filenames (not raw user-supplied paths)
- Reject unlisted items: Reject any input not on the allowlist
- No pattern matching: Don't use wildcards or regex for allowlisting paths
Canonicalize and Validate Path Containment
Resolve paths to their canonical form and verify containment:
Canonicalization process:
- Resolve symlinks and relative path segments (
..,.) - Convert to absolute canonical path
- Normalize path separators
- Verify resolved path starts with allowed base directory
- Check BEFORE opening the file
Example validation:
base_dir = "/var/www/uploads"
user_path = canonicalize(join(base_dir, user_input))
if not user_path.starts_with(base_dir):
reject()
Use Secure Path Manipulation APIs
Use language-native path APIs that prevent traversal:
- Never concatenate strings to build file paths
- Use path joining functions that normalize separators (
path.join(),Path.Combine()) - Reject dangerous patterns: Reject paths containing
.., absolute paths, or null bytes - Use filesystem APIs: Leverage built-in path validation in your language
Test with Path Traversal Payloads
Verify your fixes with attack patterns:
../../../etc/passwd(Unix/Linux)..\..\..\..\windows\system32\config\sam(Windows)- URL encoding:
%2e%2e%2f,%2e%2e\ - Double encoding:
%252e%252e%252f - Absolute paths:
/etc/passwd,C:\windows\system.ini - Null byte injection:
allowed.txt%00../../etc/passwd - Mixed separators:
..././..././etc/passwd - Ensure legitimate file access still works correctly
Language-Specific Guidance
For detailed, language-specific examples and framework-specific patterns:
- C# - Path.Combine, Path.GetFullPath for secure file access
- Go - path/filepath, os with canonical path validation
- Java - File, Path, Files API with canonical path validation
- JavaScript/Node.JS - fs, path modules, Express static with path resolution