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:
1. Resolve symlinks and relative path segments (.., .)
2. Convert to absolute canonical path
3. Normalize path separators
4. Verify resolved path starts with allowed base directory
5. 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
- Java - File, Path, Files API with canonical path validation
- JavaScript/Node.JS - fs, path modules, Express static with path resolution
Dynamic Scan Guidance
For guidance on remediating this CWE when detected by dynamic (DAST) scanners:
- Dynamic Scan Guidance - Analyzing DAST findings and mapping to source code