Allowing file uploads past cease users, especially if washed without a full understanding of the risks associated with information technology, is akin to opening the floodgates for server compromise. Naturally, despite the security concerns surrounding the ability for cease-users to upload files, it is an increasingly common requirement in modern spider web applications.

File uploads carry a significant gamble that not many are enlightened of, or how to mitigate against abuses. Worst all the same, several web applications contain insecure, unrestricted file upload mechanisms. This commodity will present eight common flawed methods of securing upload forms, and how easily an attacker could featherbed such defenses.

No Validation

A simple file upload class typically consists of an HTML form which is presented to the client and a server-side script that processes the file existence uploaded. The following example contains such an HTML class and a server-side script written in PHP.

                <course enctype="multipart/form-information" activeness="uploader.php" method="Postal service">   <input type="subconscious" proper noun="MAX_FILE_SIZE" value="100000" />   Choose a file to upload:   <input proper noun="uploadedfile" type="file" />   <input type="submit" value="Upload File" />  </form> <?php    $target_path = "uploads/";   $target_path = $target_path . basename($_FILES['uploadedfile']['proper noun']);   if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {     echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";    } else {     repeat "At that place was an error uploading the file, please endeavour again";    } ?>                              

When the PHP interpreter receives an HTTP POST method request of the multipart/form-data encoding type, the script will create a temporary file with a random name in a temporary directory on the server, for example, /var/tmp/php6yXOVs. The PHP interpreter will as well populate the global array $_FILES with the data about the uploaded file equally follows.

  • $_FILES['uploadedfile']['name']: The original name of the file on the client machine
  • $_FILES['uploadedfile']['type']: The mime blazon of the file
  • $_FILES['uploadedfile']['size']: The size of the file in bytes
  • $_FILES['uploadedfile']['tmp_name']: The temporary filename in which the uploaded file was stored on the server

The move_uploaded_file() PHP role will move the temporary file to a location provided by the user. In this case, the destination is beneath the server root. Therefore the files tin can exist accessed using a URL such as http://www.case.com/uploads/uploadedfile.txt.

In this simple case, no restrictions are imposed past the server-side script on what file types are allowed to be uploaded to the server. To such an extent, an aggressor could easily upload a malicious PHP that could lead to server compromise.

MIME-type Validation

A common mistake made when securing file upload forms is to only bank check the MIME-type returned past the awarding runtime. For example, with PHP, when a file is uploaded to the server, PHP will set up the variable $_FILES['uploadedfile']['type'] to the MIME-type provided by the web client.

Since an attacker could easily control the MIME-type by sending the server a crafted HTTP POST request, such validation is picayune for an aggressor to bypass. To such an extent, an aggressor could hands upload a malicious PHP file with an allowed MIME-type that could atomic number 82 to server compromise.

Blacklisting File Extensions

Another weak validation method that is widely used in file upload forms is to use a blacklist of types of files that have dangerous extensions. Upload forms using this mechanism would check the extension of the file that is existence uploaded and compare its file extension to a list of extensions that the application considers harmful.

While this could be somewhat effective against some file types, the selection of employing a blacklist is a poor one since practically impossible to compile a list of all possible file extensions that an assaulter could abuse use, peculiarly if the application is running within an environment that allows a large number of scripting languages, such every bit Perl, Python, Ruby, and others – the list is endless. For example, the attacker may change the messages in the extension to their capital forms (.phP, .PhP, .pHP). A whitelisting approach in this use case is by far more effective.

1 possible way an attacker could bypass a file extension blacklist on an Apache HTTP Server is to first upload an .htaccess file with the following contents.

                AddType application/x-httpd-php .jpg                              

The above configuration would instruct the Apache HTTP Server to execute JPEG images equally though they were PHP scripts. An attacker would and then go on to upload a file with a .jpg extension (a file extension that is presumably allowed), which would incorporate PHP code instead of an image and this would let for code execution.

The screenshot below shows an HTTP asking to a JPEG file that contains PHP code that invokes the phpinfo() function.

Upload Form files

Double Extensions

Some other concept for bypassing file upload validation is for an assaulter to abuse double extensions where an application extracts file extensions past looking for the . character in the filename, and extracting the cord after the dot graphic symbol. The method used to bypass this approach is similar to the method used to bypass a file extension blacklist.

It'south of import to first understand how the target spider web server handles files with multiple extensions. In this example, it shall be assumed that the target server is the Apache HTTP Server. The following is a quotation of the Apache HTTP Server documentation regarding files with multiple extensions.

Files can accept more than one extension, and the order of the extensions is normally irrelevant. For example, if the file welcome.html.fr maps onto content blazon text/html and linguistic communication French so the file welcome.fr.html volition map onto exactly the aforementioned information. If more than one extension is given which maps onto the same type of meta-information, so the i to the correct will be used, except for languages and content encodings. For example, if .gif maps to the MIME-type prototype/gif and .html maps to the MIME-blazon text/html, then the file welcome.gif.html will be associated with the MIME-blazon text/html.

Therefore, a file named index.php.123 will be interpreted equally a PHP file by the Apache HTTP Server and it will be executed. This, of course, will simply work if the final extension (in this case .123) is not specified in the list of MIME-types known to the spider web server. This bottom-known feature of the Apache HTTP Server could be very dangerous for a number of reasons. Knowing this, an attacker could upload a file containing malicious code (such as a web shell) and bypass the file upload form validation.

A far better approach to securing file upload forms is to employ a whitelisting approach. With this arroyo, merely files that lucifer a known and accustomed file extension are immune. However, in some cases, this arroyo will not piece of work as expected. For example, when the Apache HTTP Server is configured to execute PHP code, there are two ways one can specify this: using the AddHandler directive or using the AddType directive. If the AddHandler directive is used, all filenames containing the .php extension (.php, .php.jpg) will exist executed equally PHP scripts. Therefore, if an Apache HTTP Server configuration file contains the following, it may be vulnerable:

                AddHandler php5-script .php                              

On an Apache HTTP Server with the above configuration, an assailant tin can upload a file named filename.php.jpg, bypass the validation, and execute code.

Checking the Image Header

When paradigm upload only is allowed, most web applications usually validate the image header by using a server-side function such equally getimagesize() in PHP. When called, this function will render the size of an image. If the file is non a valid paradigm, pregnant that the file header is not that of an image, the function volition return FALSE. Therefore, several web applications typically check if the office returns True or FALSE and validate the uploaded file using this information.

If an attacker attempts to upload a uncomplicated PHP shell embedded in a JPEG file, the part will return simulated, finer stopping the assault. Still, even this approach can be hands bypassed if the Apache HTTP Server is using the AddHandler directive described above. If an image file is opened in an image editor, such as GIMP, ane tin edit the prototype metadata to include a comment. An attacker would insert some PHP lawmaking here as shown below.

The prototype will notwithstanding take a valid header; therefore it bypasses the getimagesize() cheque. Every bit seen in the screenshot below, the PHP lawmaking inserted in the image comments withal gets executed when the image is requested past a browser.

Protecting the Upload Binder with .htaccess

Another mutual method used to secure file upload forms is to restrict execution of scripts in an upload directory using .htaccess configuration that would typically contain the post-obit:

                AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi Options –ExecCGI                              

The above is another type of blacklist approach, which in itself is not very secure. Furthermore, as warned in the PHP documentation, the move_uploaded_file() function will overwrite any file if the destination file already exists. Because uploaded files can and will overwrite the existing ones, an aggressor could hands replace an existing .htaccess file with a modified one. This volition allows execution of specific scripts which can aid compromise a server.

Customer-Side Validation

Another common security measure in file upload forms is client-side validation of files to be uploaded. Typically, such an arroyo is more than common in ASP.NET applications, since ASP.NET offers like shooting fish in a barrel-to-utilise validation controls.

These types of validation controls allow an awarding to do regular-expression checks upon the file that is beingness uploaded, to check that the extension of the file being uploaded is specified in the list of allowed extensions. Beneath is a sample lawmaking taken from Microsoft's website.

                <asp:FileUpload ID="FileUpload1" runat="server" /><br />  <br />  <asp:Button ID="Button1" runat="server" OnClick="Button1_Click"  Text="Upload File" /> <br />  <br />  <asp:Label ID="Label1" runat="server"></asp:Characterization>  <asp:RegularExpressionValidator  id="RegularExpressionValidator1" runat="server"  ErrorMessage="Only mp3, m3u or mpeg files are allowed!"  ValidationExpression="^(([a-zA-Z]:)|(\\{two}\westward+)\$?)(\\(\west[\w].*))  +(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$"  ControlToValidate="FileUpload1"></asp:RegularExpressionValidator>  <br />  <asp:RequiredFieldValidator  id="RequiredFieldValidator1" runat="server" ErrorMessage="This is a required field!"  ControlToValidate="FileUpload1"></asp:RequiredFieldValidator>                              

This ASP.NET lawmaking uses validation controls, so the end-user is but allowed to upload .mp3, .mpeg or .m3u files to the web server. If the file blazon does not match whatsoever of the specified extensions, the validation control throws an exception and the file won't be uploaded.

Since this type of validation is done on the client side, a malicious user can easily bypass it. It is possible to write a short client-side script that will do the validation instead of the script provided by the web awarding. Without using a spider web browser, the attacker can transport HTTP POST requests to the application in guild to bypass the customer side validation and upload a malicious file.

Suggested Solution

The following is a list of best practices that should be enforced when file uploads are allowed on websites and web applications. These practices volition help avoid file upload vulnerabilities in spider web applications that are served using Apache HTTP Server, however similar rules could easily be applied to other servers both on Linux and Windows.

  • Define an .htaccess file that volition but allow access to files with allowed extensions.
  • Do not place the .htaccess file in the same directory where the uploaded files will exist stored, instead, place it in the parent directory. This way the .htaccess file can never exist overwritten by an aggressor.
  • A typical .htaccess which allows but GIF, JPG, JPEG, and PNG files should include the following (this should be adapted every bit necessary for specific requirements). The following will too prevent double extension attacks:
                        deny from all < files ~ "^westward+.(gif|jpe?g|png)$">  order deny,permit allow from all  </files>                                      
  • If possible, upload the files in a directory outside the server root.
  • Prevent overwriting of existing files (to prevent the .htaccess overwrite attack).
  • Create a whitelist of accepted MIME-types (map extensions from these MIME-types).
  • Generate a random file name and add together the previously generated extension.
  • Don't rely on client-side validation only, since it is non enough. Ideally, both server-side and client-side validation should be implemented.

Oft asked questions