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

File uploads carry a significant hazard that non many are aware of, or how to mitigate against abuses. Worst still, several web applications contain insecure, unrestricted file upload mechanisms. This article will present viii common flawed methods of securing upload forms, and how easily an attacker could bypass such defenses.

No Validation

A simple file upload form 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 instance contains such an HTML class and a server-side script written in PHP.

                <class enctype="multipart/form-information" action="uploader.php" method="POST">   <input type="hidden" name="MAX_FILE_SIZE" value="100000" />   Choose a file to upload:   <input name="uploadedfile" type="file" />   <input type="submit" value="Upload File" />  </form> <?php    $target_path = "uploads/";   $target_path = $target_path . basename($_FILES['uploadedfile']['name']);   if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {     repeat "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";    } else {     echo "There was an error uploading the file, delight endeavor again";    } ?>                              

When the PHP interpreter receives an HTTP POST method request of the multipart/form-data encoding blazon, 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 likewise populate the global array $_FILES with the data most the uploaded file equally follows.

  • $_FILES['uploadedfile']['name']: The original name of the file on the client machine
  • $_FILES['uploadedfile']['type']: The mime type 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 function will movement the temporary file to a location provided by the user. In this example, the destination is below the server root. Therefore the files can be accessed using a URL such as http://www.example.com/uploads/uploadedfile.txt.

In this uncomplicated example, no restrictions are imposed by the server-side script on what file types are allowed to be uploaded to the server. To such an extent, an assailant could easily upload a malicious PHP that could pb to server compromise.

MIME-type Validation

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

Since an attacker could hands control the MIME-blazon by sending the server a crafted HTTP POST request, such validation is piffling for an assailant to bypass. To such an extent, an aggressor could easily 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 apply a blacklist of types of files that accept dangerous extensions. Upload forms using this mechanism would bank check the extension of the file that is existence uploaded and compare its file extension to a list of extensions that the awarding considers harmful.

While this could be somewhat effective against some file types, the choice of employing a blacklist is a poor one since practically impossible to compile a list of all possible file extensions that an assailant could abuse use, especially if the application is running within an surround that allows a big number of scripting languages, such as Perl, Python, Cherry, and others – the list is endless. For instance, the aggressor may change the messages in the extension to their capital forms (.phP, .PhP, .pHP). A whitelisting approach in this use case is past far more constructive.

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

                AddType awarding/x-httpd-php .jpg                              

The higher up configuration would instruct the Apache HTTP Server to execute JPEG images every bit though they were PHP scripts. An attacker would so go along to upload a file with a .jpg extension (a file extension that is presumably allowed), which would contain PHP code instead of an image and this would allow for lawmaking execution.

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

Upload Form files

Double Extensions

Some other concept for bypassing file upload validation is for an attacker to abuse double extensions where an application extracts file extensions by looking for the . character in the filename, and extracting the string later the dot character. The method used to bypass this approach is similar to the method used to bypass a file extension blacklist.

It'due south important 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 tin have more than 1 extension, and the gild of the extensions is normally irrelevant. For instance, if the file welcome.html.fr maps onto content type text/html and language French then the file welcome.fr.html will map onto exactly the same information. If more than one extension is given which maps onto the same type of meta-data, then the one to the right will be used, except for languages and content encodings. For case, if .gif maps to the MIME-type image/gif and .html maps to the MIME-type text/html, then the file welcome.gif.html will be associated with the MIME-type text/html.

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

A far better approach to securing file upload forms is to utilise a whitelisting approach. With this approach, but files that match a known and accepted file extension are allowed. All the same, 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, in that location are 2 ways one tin 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 be executed as PHP scripts. Therefore, if an Apache HTTP Server configuration file contains the post-obit, information technology may be vulnerable:

                AddHandler php5-script .php                              

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

Checking the Image Header

When image upload only is allowed, most web applications usually validate the image header past using a server-side function such equally getimagesize() in PHP. When called, this function will return the size of an epitome. If the file is not a valid epitome, meaning that the file header is not that of an image, the part volition render FALSE. Therefore, several spider web applications typically check if the part returns TRUE or FALSE and validate the uploaded file using this data.

If an attacker attempts to upload a simple PHP trounce embedded in a JPEG file, the function will return false, effectively stopping the assail. Still, fifty-fifty this approach can be easily bypassed if the Apache HTTP Server is using the AddHandler directive described in a higher place. If an epitome file is opened in an image editor, such equally GIMP, i can edit the epitome metadata to include a comment. An attacker would insert some PHP code here as shown beneath.

The image will still have a valid header; therefore it bypasses the getimagesize() check. Every bit seen in the screenshot below, the PHP lawmaking inserted in the epitome comments still gets executed when the paradigm is requested by a browser.

Protecting the Upload Folder with .htaccess

Some other 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 higher up is some other type of blacklist approach, which in itself is not very secure. Furthermore, equally warned in the PHP documentation, the move_uploaded_file() function will overwrite whatever file if the destination file already exists. Because uploaded files can and will overwrite the existing ones, an attacker could easily supersede an existing .htaccess file with a modified i. This will allows execution of specific scripts which can assist 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 common in ASP.NET applications, since ASP.Cyberspace offers piece of cake-to-employ validation controls.

These types of validation controls allow an application to do regular-expression checks upon the file that is being uploaded, to cheque that the extension of the file beingness uploaded is specified in the list of allowed extensions. Beneath is a sample code taken from Microsoft'southward 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:Label>  <asp:RegularExpressionValidator  id="RegularExpressionValidator1" runat="server"  ErrorMessage="Just mp3, m3u or mpeg files are allowed!"  ValidationExpression="^(([a-zA-Z]:)|(\\{2}\due west+)\$?)(\\(\w[\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 code uses validation controls, so the stop-user is only allowed to upload .mp3, .mpeg or .m3u files to the web server. If the file blazon does not match any 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 customer side, a malicious user can hands bypass it. It is possible to write a brusk client-side script that will do the validation instead of the script provided past the web awarding. Without using a spider web browser, the attacker tin send HTTP Mail service requests to the application in order to bypass the client side validation and upload a malicious file.

Suggested Solution

The post-obit is a list of best practices that should be enforced when file uploads are allowed on websites and spider web applications. These practices will help avoid file upload vulnerabilities in web applications that are served using Apache HTTP Server, however similar rules could hands 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 be stored, instead, place information technology in the parent directory. This way the .htaccess file can never be overwritten by an attacker.
  • A typical .htaccess which allows only GIF, JPG, JPEG, and PNG files should include the following (this should be adapted as necessary for specific requirements). The post-obit volition besides forestall double extension attacks:
                        deny from all < files ~ "^w+.(gif|jpe?grand|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 foreclose the .htaccess overwrite attack).
  • Create a whitelist of accustomed MIME-types (map extensions from these MIME-types).
  • Generate a random file name and add the previously generated extension.
  • Don't rely on client-side validation simply, since it is non enough. Ideally, both server-side and customer-side validation should exist implemented.

Ofttimes asked questions