OWASP Web Top 10 — A01

Path Traversal

Path Traversal is a critical web application vulnerability that allows attackers to access files and directories stored outside the web root folder. By manipulating file path references, attackers can read sensitive system files, source code, and configuration data they should never be able to access.

What Is Path Traversal?

Path Traversal, also known as directory traversal or dot-dot-slash attack, is a security vulnerability that enables attackers to read arbitrary files on the server running an application. This occurs when an application uses user-supplied input to construct file paths without proper validation or sanitization. The vulnerability gets its name from the use of "../" sequences (dot-dot-slash), which navigate up the directory tree in most operating systems.

The attack works by exploiting insufficient security validation of user-supplied file names. When an application concatenates user input directly into file system operations, an attacker can inject path traversal sequences like "../../etc/passwd" to escape the intended directory and access sensitive files anywhere on the file system. Attackers can also use various encoding techniques such as URL encoding (%2e%2e%2f), double encoding, unicode normalization, or null byte injection to bypass basic input filters.

Path Traversal is classified under OWASP A01 (Broken Access Control) in the 2021 Top 10. Despite being a well-known vulnerability with straightforward prevention methods, it continues to appear in modern applications, particularly in file upload handlers, document viewers, image processors, and backup/restore functionality. The vulnerability is especially dangerous because it can lead to full system compromise when combined with other attack vectors.

How It Works

1
Application accepts file name input

The application provides a feature that accepts a file name or path parameter from the user. This could be a document download endpoint, an image viewer, a template renderer, or any feature that serves files based on user input.

2
Input is used to construct file path

The application takes the user-supplied file name and directly concatenates it with a base directory path without proper validation. For example, it might build a path like /var/www/uploads/ + userInput to construct the full file path.

3
Attacker injects traversal sequences

Instead of providing a legitimate file name like document.pdf, the attacker injects path traversal sequences such as ../../../../etc/passwd. These dot-dot-slash sequences navigate up the directory tree, escaping the intended base directory.

4
File path resolves outside intended directory

The resulting path becomes /var/www/uploads/../../../../etc/passwd, which the operating system resolves to /etc/passwd. The traversal sequences effectively cancel out parts of the base path, allowing access to arbitrary locations on the file system.

5
Sensitive file is accessed

The application reads and returns the contents of the targeted file without any awareness that it has been tricked into accessing a file outside its intended directory. The attacker successfully retrieves sensitive system files, configuration data, or source code.

Vulnerable Code Example

Vulnerable — Java / Spring Boot
@RestController
public class FileController {

    private static final String BASE_DIR = "/var/www/uploads/";

    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile(
            @RequestParam String filename) throws IOException {

        // VULNERABLE: User input is directly concatenated
        // into the file path without validation
        Path filePath = Paths.get(BASE_DIR + filename);

        Resource resource = new UrlResource(filePath.toUri());

        if (resource.exists()) {
            return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + filename + "\"")
                .body(resource);
        }
        return ResponseEntity.notFound().build();
    }
}

// An attacker can access system files by submitting:
// GET /download?filename=../../../../etc/passwd
//
// Resulting path:
// /var/www/uploads/../../../../etc/passwd
// Which resolves to: /etc/passwd
//
// The attacker successfully reads sensitive system files.

Secure Code Example

Secure — Java / Spring Boot (Path Validation)
@RestController
public class FileController {

    private static final Path BASE_DIR = Paths.get("/var/www/uploads/")
        .toAbsolutePath().normalize();
    private static final Set<String> ALLOWED_EXTENSIONS =
        Set.of("pdf", "docx", "txt", "png", "jpg");

    @GetMapping("/download")
    public ResponseEntity<Resource> downloadFile(
            @RequestParam String filename) throws IOException {

        // SECURE: Validate and sanitize the filename
        // 1. Remove any path separators from filename
        String sanitized = Paths.get(filename).getFileName().toString();

        // 2. Validate file extension against allowlist
        String extension = sanitized.substring(
            sanitized.lastIndexOf('.') + 1).toLowerCase();
        if (!ALLOWED_EXTENSIONS.contains(extension)) {
            return ResponseEntity.badRequest().build();
        }

        // 3. Construct the full path and normalize it
        Path filePath = BASE_DIR.resolve(sanitized).normalize();

        // 4. Critical: Verify the resolved path still starts with BASE_DIR
        if (!filePath.startsWith(BASE_DIR)) {
            return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
        }

        Resource resource = new UrlResource(filePath.toUri());

        if (resource.exists() && resource.isReadable()) {
            return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + sanitized + "\"")
                .body(resource);
        }
        return ResponseEntity.notFound().build();
    }
}

// With proper validation, path traversal attempts fail:
// Input: ../../../../etc/passwd
// After sanitization: passwd (path separators removed)
// Resolved path: /var/www/uploads/passwd
// startsWith check: passes (within BASE_DIR)
// Result: File not found (passwd doesn't exist in uploads)

Types of Path Traversal

Relative Path Traversal

The most common form of path traversal attack. Attackers use ../ sequences (dot-dot-slash) to navigate up the directory tree and escape the intended base directory. For example, ../../../etc/passwd moves up three directory levels to access the /etc directory. Variations include using backslashes on Windows (..\..\..\), multiple slashes (....//....//), or combining them in various ways to bypass simple pattern-matching filters.

Absolute Path Traversal

Attackers provide a complete absolute path directly, such as /etc/passwd on Unix systems or C:\Windows\System32\config\SAM on Windows. This bypasses the base directory entirely if the application doesn't validate that the resolved path starts with the intended base directory. Some applications mistakenly trust that prepending a base path provides security, but if the user input begins with a path separator, it overrides the base path completely in some file system APIs.

Encoding & Filter Bypass

Sophisticated attackers use various encoding techniques to evade basic input filters. URL encoding converts ../ to %2e%2e%2f, double encoding becomes %252e%252e%252f, and unicode/UTF-8 encoding can represent dots as %c0%2e. Additional techniques include null byte injection (%00) to terminate strings early, 16-bit unicode encoding, and exploiting normalization differences between validation and file access code. Filters that only check for literal "../" strings are easily bypassed by these encoding variations.

Impact

A successful Path Traversal attack can have severe consequences, ranging from information disclosure to complete system compromise. The impact depends on the permissions of the web server process, the files accessible on the system, and what the attacker can do with the disclosed information.

Source code disclosure

Attackers can read the application's source code files, revealing business logic, proprietary algorithms, hardcoded credentials, API keys, and other vulnerabilities in the code. This information can be used to plan more sophisticated attacks tailored to the specific application architecture.

Configuration and credential theft

Access to configuration files exposes database credentials, API secrets, encryption keys, and internal network information. Common targets include .env files, config.php, application.properties, web.config, and cloud provider credential files like ~/.aws/credentials.

System file access

Reading sensitive operating system files like /etc/passwd, /etc/shadow (if permissions allow), Windows SAM database, or registry hives can provide information for privilege escalation attacks. Log files may contain session tokens, user activity patterns, or additional vulnerabilities.

Remote code execution via log poisoning

In some scenarios, attackers can combine path traversal with log file injection. By injecting malicious code into log files (e.g., through User-Agent headers or error messages) and then using path traversal to include those log files as executable code (via PHP include, JSP include, etc.), attackers can achieve remote code execution and full server compromise.

Prevention Checklist

Use allowlists for file names

Maintain a predefined list of allowed file names or use indirect references like database IDs mapped to file names. Instead of accepting arbitrary file names from users, map numeric IDs to actual file paths server-side. This completely eliminates the possibility of path manipulation by preventing direct file path input.

Canonicalize and validate paths

Always resolve paths to their canonical absolute form using functions like Path.normalize(), realpath(), or File.getCanonicalPath(). After canonicalization, verify that the resolved path starts with the expected base directory. This prevents both relative and absolute path traversal attempts.

Strip path separators from user input

Use Path.getFileName() or equivalent functions to extract only the file name portion, automatically removing any directory separators and path traversal sequences. This ensures that user input can only specify a file name, not a path structure.

Validate file extensions with allowlists

Maintain a strict allowlist of permitted file extensions and reject any files that don't match. Check the extension after sanitization and normalization to prevent double-extension attacks. Use case-insensitive comparison and check for null byte injection attempts that might truncate the extension.

Implement proper access controls

Run the web application with minimal file system permissions. The application should only have read access to files it legitimately needs to serve, and should run under a dedicated user account with restricted permissions. This limits the damage an attacker can do even if path traversal is successful.

Never use user input in file system APIs directly

Avoid concatenating user input directly into file paths. Use parameterized file system APIs, path builder functions, or abstraction layers that handle sanitization automatically. Treat file paths from users the same way you treat SQL queries—never trust user input without thorough validation and sanitization.

Real-World Examples

2019

Fortinet VPN (CVE-2018-13379)

A critical path traversal vulnerability in Fortinet's FortiOS SSL VPN allowed unauthenticated attackers to download system files by manipulating the file path parameter. Attackers exploited this to steal VPN credentials, leading to widespread breaches. The vulnerability affected hundreds of thousands of devices and was actively exploited in the wild, resulting in major government and corporate compromises.

2019

Citrix ADC (CVE-2019-19781)

Citrix Application Delivery Controller and Gateway contained a path traversal vulnerability that allowed remote code execution. Attackers could traverse directories to access and execute arbitrary files on the system. The vulnerability was so severe that organizations worldwide rushed to patch their Citrix infrastructure. Exploitation led to ransomware attacks and data breaches affecting major enterprises and government agencies.

2021

Apache HTTP Server (CVE-2021-41773)

A path traversal vulnerability in Apache HTTP Server 2.4.49 allowed attackers to map URLs to files outside the configured document root. By sending specially crafted requests with encoded dot-dot-slash sequences, attackers could read source code and configuration files. When combined with CGI script execution (CVE-2021-42013), it led to remote code execution, making it one of the most critical Apache vulnerabilities in recent years.

2018

Zip Slip Vulnerability

Zip Slip is a widespread path traversal vulnerability in archive extraction functionality. When extracting ZIP files, many libraries and applications failed to validate that file paths within the archive don't contain traversal sequences. Attackers could craft malicious ZIP files containing entries like ../../evil.sh that would extract outside the target directory, potentially overwriting critical system files or application code, leading to remote code execution.

Ready to Test Your Knowledge?

Put what you have learned into practice. Try identifying and fixing Path Traversal vulnerabilities in our interactive coding challenges, or explore more security guides to deepen your understanding.