Friday, September 11, 2009

Why File Upload Forms are a major security threat part2

Case 4: Double extensions (part 1)

This case’s security measures, as a concept are very similar to that one used in case 3. Though instead of simply checking the extension string present in the filename, the developer is extracting the file extension by looking for the ‘.’ character in the filename, and extracting the string after the dot character.

The method used to bypass this approach is a bit more complicated, but still realistic. First, let’s have a look at how Apache handles files with multiple extensions. A quote from the Apache manual states:

“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 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-information, then the one to the right will 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 will be associated with the MIME-type text/html.”

Therefore a file named ‘filename.php.123’, will be interpreted as a PHP file and will be executed. This only works if the last extension (in our case .123), is not specified in the list of mime-types known to the web server. Web developers, usually are not aware of such ‘feature’ in Apache, which can be very dangerous for a number of reasons. Knowing this, an attacker can upload a file named shell.php.123 and bypass the file upload form protection. The script will compute the last extension (.123), and concludes that this extension is not in the list of dangerous extension. Having said that, it is impossible to predict all the possible random extensions a malicious user will use to be able to upload a file on your web server.

Case 5: Double extensions (part 2)

A better approach to securing file upload forms is the white list approach. In this case, the developer defines a list of known/accepted extensions and does not allow extensions that are not specified in the list.

However, in some cases this approach will not work as expected. When Apache is configured to execute PHP code, there are 2 ways one can specify this: to use the AddHandler directive, or to use the AddType directive. If AddHandler directive is used, all filenames containing the ‘.php’ extension (e.g. ‘.php’, ‘.php.jpg’) will be executed as a PHP script. Therefore, if your Apache configuration file contains the following line, you may be vulnerable:

AddHandler php5-script .php

An attacker can upload a file named ‘filename.php.jpg’ and bypass the protection, and will be able to execute the code.

Case 6: Checking the image header

When images only are allowed to be uploaded, developers usually validate the image header by using the PHP function called getimagesize. When called, this function will return the size of an image. If the image validation is invalid, which means that the header is incorrect, the function will return a false. Therefore a developer typically checks if the function returns a true or false, and validate the uploaded file using this information. So, if a malicious user tries to upload a simple PHP shell embedded in a jpg file, the function will return false and he won’t be allowed to upload the file. However, even this approach can be easily bypassed. If a picture is opened in an image editor, like Gimp, one can edit the image comment, where PHP code is inserted, as shown below.



The image will still have a valid header; therefore it bypasses the getimagesize PHP check. As seen in the screen shot below, the PHP code inserted in the image comments still gets executed when the image is requested from a normal web browser:



Case 7: Protecting the upload folder with .htaccess

Another popular way of securing file upload forms, is to protect the folder where the files are uploaded using .htaccess file. The idea is to restrict execution of script files in this folder. A .htaccess file typically contains the below code when used in this kind of scenario:

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

The above is another type of blacklist approach, which in itself is not very secure. In the PHP manual, in the move_uploaded_file section, there is a warning which states ‘If the destination file already exists, it will be overwritten.’

Because uploaded files can and will overwrite the existing ones, a malicious user can easily replace the .htaccess file with his own modified version. This will allows him to execute specific scripts which can help him compromise the server.

Case 8: Client-side validation

Another common type of security used in file upload forms, is client-side validation of files to be uploaded. Typically, such approach is more common in ASP.NET applications, since ASP.NET offers easy to use validation controls.
A malicious user can easily bypass this type of validation. It is possible to write a short client side script that will do the validation instead of the script provided by the web application. Without using a web browser, the attacker can use an application that allows sending of HTTP POST requests to be able to upload the file.

Suggested Solution

Below is a list of best practices that should be enforced when file uploads are allowed on websites and web applications. These practices will help you securing file upload forms used in web applications;

*
Define a .htaccess file that will 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. It should be placed in the parent directory.
*
A typical .htaccess which allows only gif, jpg, jpeg and png files should include the following (adapt it for your own need). This will also prevent double extension attacks.


deny from all

<Files ~ "^\w+\.(gif|jpe?g|png)$">

order 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 list 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 one should have both server-side and client-side validation implemented.

0 comments:

Post a Comment