Allowing file uploads by end users, peculiarly if done without a total understanding of the risks associated with information technology, is akin to opening the floodgates for server compromise. Naturally, despite the security concerns surrounding the power for end-users to upload files, it is an increasingly common requirement in mod spider web applications.

File uploads comport a meaning risk that not many are enlightened of, or how to mitigate confronting abuses. Worst still, several spider web applications contain insecure, unrestricted file upload mechanisms. This article volition present eight common flawed methods of securing upload forms, and how easily an assailant could bypass such defenses.

No Validation

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

                <form enctype="multipart/class-data" 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)) {     echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";    } else {     repeat "There was an error uploading the file, please endeavor again";    } ?>                              

When the PHP interpreter receives an HTTP Mail method request of the multipart/form-data encoding type, the script volition create a temporary file with a random proper name in a temporary directory on the server, for case, /var/tmp/php6yXOVs. The PHP interpreter will also populate the global array $_FILES with the data nigh 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 move the temporary file to a location provided past the user. In this case, the destination is below the server root. Therefore the files tin be accessed using a URL such as http://world wide web.example.com/uploads/uploadedfile.txt.

In this simple case, 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 mistake fabricated when securing file upload forms is to only check the MIME-blazon returned by the awarding runtime. For example, with PHP, when a file is uploaded to the server, PHP volition set the variable $_FILES['uploadedfile']['blazon'] 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 assailant to bypass. To such an extent, an aggressor could easily upload a malicious PHP file with an immune 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 use a blacklist of types of files that take 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 confronting some file types, the option 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, especially if the application is running within an environment that allows a large number of scripting languages, such as Perl, Python, Ruby, and others – the listing is endless. For instance, the aggressor may modify the messages in the extension to their uppercase forms (.phP, .PhP, .pHP). A whitelisting arroyo in this use case is past far more than effective.

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

                AddType application/ten-httpd-php .jpg                              

The above configuration would instruct the Apache HTTP Server to execute JPEG images every bit though they were PHP scripts. An attacker would then keep 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 allow for code 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 assailant to corruption double extensions where an application extracts file extensions by looking for the . character in the filename, and extracting the string afterward 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 beginning understand how the target spider web server handles files with multiple extensions. In this instance, information technology shall be assumed that the target server is the Apache HTTP Server. The post-obit is a quotation of the Apache HTTP Server documentation regarding files with multiple extensions.

Files can have more than than one extension, and the order of the extensions is normally irrelevant. For case, if the file welcome.html.fr maps onto content type text/html and language French and so the file welcome.fr.html will map onto exactly the aforementioned data. If more than than i extension is given which maps onto the same type of meta-information, so the 1 to the right will be used, except for languages and content encodings. For case, if .gif maps to the MIME-type paradigm/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 as a PHP file past the Apache HTTP Server and it will be executed. This, of course, will simply work if the final extension (in this case .123) is non specified in the list of MIME-types known to the web server. This lesser-known characteristic 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 beat) and bypass the file upload form validation.

A far better approach to securing file upload forms is to employ a whitelisting approach. With this approach, just files that lucifer a known and accepted file extension are allowed. However, in some cases, this approach will not work equally expected. For case, when the Apache HTTP Server is configured to execute PHP code, at that place 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 equally PHP scripts. Therefore, if an Apache HTTP Server configuration file contains the following, information technology may be vulnerable:

                AddHandler php5-script .php                              

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

Checking the Image Header

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

If an attacker attempts to upload a simple PHP shell embedded in a JPEG file, the function will return faux, effectively stopping the assault. However, even this approach can be easily bypassed if the Apache HTTP Server is using the AddHandler directive described in a higher place. If an image file is opened in an image editor, such equally GIMP, one tin edit the prototype metadata to include a comment. An attacker would insert some PHP code hither equally shown below.

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

Protecting the Upload Binder with .htaccess

Another 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 following:

                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, every bit warned in the PHP documentation, the move_uploaded_file() function will overwrite any file if the destination file already exists. Because uploaded files tin can and will overwrite the existing ones, an aggressor could easily replace an existing .htaccess file with a modified 1. This will allows execution of specific scripts which can assistance compromise a server.

Client-Side Validation

Some other mutual security measure in file upload forms is client-side validation of files to exist uploaded. Typically, such an approach is more common in ASP.Net applications, since ASP.Net offers easy-to-use 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 immune extensions. Beneath 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:Label>  <asp:RegularExpressionValidator  id="RegularExpressionValidator1" runat="server"  ErrorMessage="But 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.Cyberspace code uses validation controls, so the end-user is only immune to upload .mp3, .mpeg or .m3u files to the web server. If the file type 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 client side, a malicious user can hands bypass it. It is possible to write a curt customer-side script that will practice the validation instead of the script provided by the spider web application. Without using a web browser, the attacker can send HTTP Post requests to the application in society to featherbed 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 web applications. These practices will help 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 will only allow admission to files with allowed extensions.
  • Exercise not place the .htaccess file in the same directory where the uploaded files will exist stored, instead, place it in the parent directory. This style 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 following will also prevent double extension attacks:
                        deny from all < files ~ "^w+.(gif|jpe?thou|png)$">  order deny,allow allow from all  </files>                                      
  • If possible, upload the files in a directory exterior 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 the previously generated extension.
  • Don't rely on client-side validation only, since it is not enough. Ideally, both server-side and client-side validation should be implemented.

Ofttimes asked questions