Allowing file uploads by end users, especially if done without a total 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, it is an increasingly mutual requirement in modernistic web applications.

File uploads carry a significant run a risk that not 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 eight common flawed methods of securing upload forms, and how easily an aggressor 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 being uploaded. The following instance contains such an HTML form and a server-side script written in PHP.

                <course 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 blazon="submit" value="Upload File" />  </grade> <?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 {     repeat "At that place was an error uploading the file, please endeavor again";    } ?>                              

When the PHP interpreter receives an HTTP Post method asking of the multipart/form-data encoding type, the script volition 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 information about the uploaded file as follows.

  • $_FILES['uploadedfile']['name']: The original proper noun 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 part will move the temporary file to a location provided by the user. In this case, the destination is below the server root. Therefore the files can be accessed using a URL such as http://world wide web.example.com/uploads/uploadedfile.txt.

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

MIME-type Validation

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

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

Blacklisting File Extensions

Another weak validation method that is widely used in file upload forms is to employ a blacklist of types of files that have dangerous extensions. Upload forms using this mechanism would bank check the extension of the file that is being 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 i since practically impossible to compile a listing of all possible file extensions that an assaulter could abuse use, especially if the application is running within an environment that allows a big number of scripting languages, such as Perl, Python, Ruby, and others – the listing is endless. For example, the attacker may change the letters in the extension to their capital forms (.phP, .PhP, .pHP). A whitelisting approach in this use case is past far more constructive.

One 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 awarding/x-httpd-php .jpg                              

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

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

Upload Form files

Double Extensions

Another 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 afterwards the dot character. The method used to bypass this arroyo is similar to the method used to bypass a file extension blacklist.

Information technology'southward important to first sympathise how the target web server handles files with multiple extensions. In this instance, it shall exist causeless 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 have 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 language French then the file welcome.fr.html will map onto exactly the same information. If more than i extension is given which maps onto the same blazon of meta-data, so the ane 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 volition exist interpreted as a PHP file by the Apache HTTP Server and it will be executed. This, of course, will just work if the concluding extension (in this instance .123) is not specified in the list of MIME-types known to the spider web server. This lesser-known characteristic of the Apache HTTP Server could be very dangerous for a number of reasons. Knowing this, an aggressor could upload a file containing malicious lawmaking (such as a web vanquish) and bypass the file upload form validation.

A far amend approach to securing file upload forms is to use a whitelisting arroyo. With this approach, merely files that lucifer a known and accepted file extension are allowed. However, in some cases, this approach will non work as expected. For example, when the Apache HTTP Server is configured to execute PHP code, in that location 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 be executed every bit PHP scripts. Therefore, if an Apache HTTP Server configuration file contains the following, it may exist vulnerable:

                AddHandler php5-script .php                              

On an Apache HTTP Server with the above configuration, an attacker 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 spider web applications normally validate the image header past using a server-side part such as getimagesize() in PHP. When called, this function will render the size of an epitome. If the file is not a valid image, significant that the file header is not that of an epitome, the function will return Simulated. 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 simple PHP shell embedded in a JPEG file, the office will render fake, effectively stopping the assault. However, fifty-fifty this approach tin 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 every bit GIMP, i can edit the image 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 beneath, the PHP lawmaking inserted in the image comments still gets executed when the image is requested by a browser.

Protecting the Upload Folder with .htaccess

Some other common method used to secure file upload forms is to restrict execution of scripts in an upload directory using .htaccess configuration that would typically incorporate the following:

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

The in a higher place is some other type of blacklist arroyo, which in itself is not very secure. Furthermore, equally warned in the PHP documentation, the move_uploaded_file() function volition overwrite any file if the destination file already exists. Because uploaded files can and will overwrite the existing ones, an attacker could easily replace an existing .htaccess file with a modified i. This volition allows execution of specific scripts which can assist compromise a server.

Client-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 mutual in ASP.NET applications, since ASP.Net offers easy-to-use 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 being uploaded is specified in the list of allowed extensions. Below is a sample code 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]:)|(\\{2}\w+)\$?)(\\(\w[\westward].*))  +(.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, and so the end-user is only allowed to upload .mp3, .mpeg or .m3u files to the spider web server. If the file type does not lucifer 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 client side, a malicious user tin hands bypass information technology. It is possible to write a brusk client-side script that will practice the validation instead of the script provided by the web application. Without using a web browser, the attacker tin can transport HTTP Mail requests to the application in order 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 will aid avoid file upload vulnerabilities in web applications that are served using Apache HTTP Server, even so similar rules could hands be applied to other servers both on Linux and Windows.

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

Oftentimes asked questions