Allowing file uploads by end users, especially if done 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 power for end-users to upload files, information technology is an increasingly mutual requirement in mod web applications.

File uploads carry a significant risk that non many are enlightened of, or how to mitigate against abuses. Worst still, several spider web applications contain insecure, unrestricted file upload mechanisms. This article volition nowadays eight mutual flawed methods of securing upload forms, and how easily an attacker could bypass such defenses.

No Validation

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

                <form enctype="multipart/form-information" action="uploader.php" method="POST">   <input type="hidden" name="MAX_FILE_SIZE" value="100000" />   Cull 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']['proper name']) . " has been uploaded";    } else {     repeat "At that place was an error uploading the file, delight try again";    } ?>                              

When the PHP interpreter receives an HTTP POST method asking 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 case, /var/tmp/php6yXOVs. The PHP interpreter will besides populate the global assortment $_FILES with the information about the uploaded file as follows.

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

In this simple example, 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 attacker 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 cheque the MIME-blazon returned by the application runtime. For example, with PHP, when a file is uploaded to the server, PHP will set the variable $_FILES['uploadedfile']['blazon'] to the MIME-type provided by the spider web client.

Since an attacker could easily command the MIME-blazon by sending the server a crafted HTTP POST request, such validation is trivial for an attacker to bypass. To such an extent, an attacker 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 have dangerous extensions. Upload forms using this mechanism would cheque the extension of the file that is being uploaded and compare its file extension to a listing of extensions that the application considers harmful.

While this could be somewhat effective confronting some file types, the choice of employing a blacklist is a poor one since practically impossible to compile a listing of all possible file extensions that an attacker could abuse use, especially if the application is running within an environs that allows a large number of scripting languages, such as Perl, Python, Ruby, and others – the list is countless. For example, the attacker may modify the letters in the extension to their uppercase forms (.phP, .PhP, .pHP). A whitelisting approach in this apply case is past far more effective.

One possible way an assailant 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 as though they were PHP scripts. An attacker would then go on to upload a file with a .jpg extension (a file extension that is presumably allowed), which would contain PHP lawmaking instead of an prototype and this would allow for code execution.

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

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 graphic symbol. The method used to bypass this approach is like to the method used to bypass a file extension blacklist.

It's important to outset sympathise how the target web server handles files with multiple extensions. In this case, information technology shall be causeless 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 one extension, and the order of the extensions is normally irrelevant. For example, if the file welcome.html.fr maps onto content type text/html and linguistic communication French then the file welcome.fr.html volition map onto exactly the same information. If more than than 1 extension is given which maps onto the same type of meta-information, then the 1 to the right volition be used, except for languages and content encodings. For example, if .gif maps to the MIME-type image/gif and .html maps to the MIME-type text/html, then the file welcome.gif.html volition be associated with the MIME-type text/html.

Therefore, a file named index.php.123 volition be interpreted as a PHP file by the Apache HTTP Server and it will be executed. This, of course, will only work if the last extension (in this case .123) is not specified in the list of MIME-types known to the web server. This bottom-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 spider web trounce) and bypass the file upload course validation.

A far better arroyo to securing file upload forms is to employ a whitelisting approach. With this approach, simply files that friction match a known and accustomed file extension are allowed. All the same, in some cases, this arroyo will not work as expected. For instance, when the Apache HTTP Server is configured to execute PHP lawmaking, 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) volition be executed as PHP scripts. Therefore, if an Apache HTTP Server configuration file contains the post-obit, it may be vulnerable:

                AddHandler php5-script .php                              

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

Checking the Image Header

When epitome upload but is immune, near spider web applications unremarkably validate the prototype header by using a server-side function such equally getimagesize() in PHP. When called, this function will return the size of an image. If the file is non a valid image, meaning that the file header is not that of an image, the function will render Faux. Therefore, several web applications typically check if the part returns TRUE or FALSE and validate the uploaded file using this information.

If an aggressor attempts to upload a simple PHP beat embedded in a JPEG file, the office will render false, finer stopping the assault. However, fifty-fifty this arroyo can be easily bypassed if the Apache HTTP Server is using the AddHandler directive described above. If an epitome file is opened in an image editor, such as GIMP, one tin edit the image metadata to include a comment. An attacker would insert some PHP code here as shown below.

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

Protecting the Upload Folder 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 incorporate the following:

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

The to a higher place is some other blazon of blacklist approach, which in itself is not very secure. Furthermore, as warned in the PHP documentation, the move_uploaded_file() function will overwrite whatever file if the destination file already exists. Considering uploaded files can and will overwrite the existing ones, an attacker could easily replace an existing .htaccess file with a modified one. This will 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 approach is more mutual in ASP.NET applications, since ASP.NET offers piece of cake-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 check that the extension of the file existence uploaded is specified in the listing 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:Characterization ID="Label1" runat="server"></asp:Label>  <asp:RegularExpressionValidator  id="RegularExpressionValidator1" runat="server"  ErrorMessage="Only mp3, m3u or mpeg files are allowed!"  ValidationExpression="^(([a-zA-Z]:)|(\\{two}\w+)\$?)(\\(\westward[\west].*))  +(.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 end-user is just allowed to upload .mp3, .mpeg or .m3u files to the web server. If the file type does not friction 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 washed on the customer side, a malicious user can easily featherbed information technology. 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 tin can send HTTP Mail service requests to the application in gild to bypass the client 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 spider web applications. These practices will help avoid file upload vulnerabilities in spider web applications that are served using Apache HTTP Server, nonetheless like rules could easily be applied to other servers both on Linux and Windows.

  • Ascertain an .htaccess file that will just permit access to files with immune extensions.
  • Practise 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 tin never be overwritten by an assailant.
  • A typical .htaccess which allows only GIF, JPG, JPEG, and PNG files should include the post-obit (this should exist adapted equally necessary for specific requirements). The post-obit will also prevent double extension attacks:
                        deny from all < files ~ "^w+.(gif|jpe?1000|png)$">  society deny,allow let from all  </files>                                      
  • If possible, upload the files in a directory outside the server root.
  • Preclude overwriting of existing files (to forestall 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 client-side validation just, since it is non enough. Ideally, both server-side and customer-side validation should exist implemented.

Frequently asked questions