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

File uploads carry a significant risk that not many are aware of, or how to mitigate confronting abuses. Worst still, several spider web applications contain insecure, unrestricted file upload mechanisms. This article will present eight common flawed methods of securing upload forms, and how hands an assailant could featherbed such defenses.

No Validation

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

                <form enctype="multipart/form-data" action="uploader.php" method="Mail">   <input type="hidden" proper name="MAX_FILE_SIZE" value="100000" />   Choose a file to upload:   <input proper name="uploadedfile" type="file" />   <input type="submit" value="Upload File" />  </form> <?php    $target_path = "uploads/";   $target_path = $target_path . basename($_FILES['uploadedfile']['proper name']);   if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {     echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";    } else {     echo "In that location was an fault uploading the file, please try again";    } ?>                              

When the PHP interpreter receives an HTTP Post method request of the multipart/class-information encoding type, the script will create a temporary file with a random name in a temporary directory on the server, for instance, /var/tmp/php6yXOVs. The PHP interpreter will also populate the global array $_FILES with the data near the uploaded file as follows.

  • $_FILES['uploadedfile']['name']: The original name of the file on the client auto
  • $_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 motility 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://www.example.com/uploads/uploadedfile.txt.

In this elementary 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 attacker could easily upload a malicious PHP that could lead to server compromise.

MIME-type Validation

A common fault fabricated when securing file upload forms is to only check the MIME-type returned past the application runtime. For example, with PHP, when a file is uploaded to the server, PHP volition set the variable $_FILES['uploadedfile']['type'] to the MIME-blazon provided by the web customer.

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

Blacklisting File Extensions

Some other 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 being 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 choice of employing a blacklist is a poor one since practically impossible to compile a list of all possible file extensions that an attacker could abuse utilise, especially if the awarding is running within an surroundings that allows a large number of scripting languages, such equally Perl, Python, Cerise, 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 arroyo in this utilize case is by far more effective.

I possible way an assaulter could bypass a file extension blacklist on an Apache HTTP Server is to get-go upload an .htaccess file with the post-obit contents.

                AddType awarding/x-httpd-php .jpg                              

The to a higher place configuration would instruct the Apache HTTP Server to execute JPEG images equally though they were PHP scripts. An attacker would then continue to upload a file with a .jpg extension (a file extension that is presumably immune), which would contain PHP lawmaking instead of an image and this would permit for lawmaking execution.

The screenshot beneath shows an HTTP asking 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 after the dot character. The method used to bypass this approach is similar to the method used to bypass a file extension blacklist.

It's important to first empathize how the target spider web server handles files with multiple extensions. In this example, information technology 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 one extension, and the society of the extensions is commonly irrelevant. For case, if the file welcome.html.fr maps onto content type text/html and linguistic communication French then the file welcome.fr.html will map onto exactly the aforementioned information. If more one extension is given which maps onto the same type of meta-information, then the ane to the right volition 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, and 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 will exist executed. This, of form, will only piece of work if the last extension (in this case .123) is not specified in the listing of MIME-types known to the web server. This bottom-known characteristic of the Apache HTTP Server could be very unsafe for a number of reasons. Knowing this, an attacker could upload a file containing malicious code (such as a web shell) and featherbed the file upload form validation.

A far better arroyo to securing file upload forms is to employ a whitelisting approach. With this approach, only files that match a known and accepted file extension are allowed. However, in some cases, this arroyo will not piece of work equally expected. For example, when the Apache HTTP Server is configured to execute PHP code, at that place are ii ways i 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) volition exist executed every bit PHP scripts. Therefore, if an Apache HTTP Server configuration file contains the post-obit, information technology may exist vulnerable:

                AddHandler php5-script .php                              

On an Apache HTTP Server with the to a higher place configuration, an assailant tin can upload a file named filename.php.jpg, featherbed the validation, and execute lawmaking.

Checking the Image Header

When epitome upload only is allowed, near web applications normally validate the image header past using a server-side function such as getimagesize() in PHP. When called, this function will render the size of an image. If the file is non a valid epitome, significant that the file header is not that of an prototype, the part will return Imitation. Therefore, several spider web applications typically check if the function returns True or False and validate the uploaded file using this information.

If an assailant attempts to upload a elementary PHP crush embedded in a JPEG file, the function will return false, effectively stopping the attack. However, even this approach can be easily bypassed if the Apache HTTP Server is using the AddHandler directive described above. If an epitome file is opened in an prototype editor, such as GIMP, ane can edit the image metadata to include a comment. An assaulter would insert some PHP code hither equally shown below.

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

Protecting the Upload Binder 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 contain the post-obit:

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

The above is some other type of blacklist approach, which in itself is not very secure. Furthermore, as warned in the PHP documentation, the move_uploaded_file() part will overwrite whatever file if the destination file already exists. Because uploaded files tin and will overwrite the existing ones, an attacker could easily supercede an existing .htaccess file with a modified one. This will allows execution of specific scripts which can assistance compromise a server.

Client-Side Validation

Some other common security mensurate 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.NET offers easy-to-employ validation controls.

These types of validation controls allow an application to practise regular-expression checks upon the file that is existence 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:Push 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 immune!"  ValidationExpression="^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\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 cease-user is just allowed to upload .mp3, .mpeg or .m3u files to the web server. If the file type does non lucifer whatsoever of the specified extensions, the validation command throws an exception and the file won't be uploaded.

Since this type of validation is washed on the client side, a malicious user can hands featherbed it. It is possible to write a brusk customer-side script that will do the validation instead of the script provided by the web awarding. Without using a web browser, the attacker can ship 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 immune on websites and web applications. These practices will assistance avoid file upload vulnerabilities in 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 only 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 it in the parent directory. This manner the .htaccess file can never be overwritten past an assaulter.
  • 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 following will also preclude double extension attacks:
                        deny from all < files ~ "^w+.(gif|jpe?grand|png)$">  lodge deny,allow 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 accustomed MIME-types (map extensions from these MIME-types).
  • Generate a random file name and add the previously generated extension.
  • Don't rely on customer-side validation only, since it is non enough. Ideally, both server-side and client-side validation should be implemented.

Frequently asked questions