How can I protect a PHP image upload script from exploits?

I've created (using a script and some help from Stack and some help from friends; I know very little about PHP) a simple page for a local non-profit publication where people can upload photos.

I'm not great with security (from a basis of ignorance, not deliberate negligence) but I've taken the following steps to protect this page:

• the PHP script is set to only accept .jpg, .png and .tif files for upload; • the subfolder that it saves the form content to has permissions set at 700, and the subfolder it saves uploaded photos to has permissions set at 700; • according to documentation, my host has the following configuration to ensure that only .php files run as .php:

<FilesMatch \.php$>
    SetHandler php52-fcgi
</FilesMatch>

• I’ve put an .htaccess file in the relevant (main and saved content) folders:

RemoveHandler .php
RemoveHandler .inc
RemoveHandler .pl
RemoveHandler .cgi
RemoveHandler .py
RemoveHandler .fcgi

Overnight, however, somebody found this test page and submitted what seems to be a perfectly benign test message and small .jpg. This is a private test page with a non-intuitive URL that only I and about three other people know about; none of the others sent this test.

This obviously has me worried that there's something hinky going on, and I'm worried that I don't know enough about security to make sure this page is safe.

Is there something obvious that I'm missing?

Answers


When dealing with uploaded you should keep in mind that all the data you can find in the $_FILES array can be faked. It's traveling through HTTP so it's pretty easy to give the image/jpg mime to an executable file for exemple.

1- Check the true mime

PHP come with some function to check the real mime of a file. For that you should use fileinfo

$finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic");
$filename = "/var/tmp/afile.jpg";
echo $finfo->file($filename);

2- Check the image's properties

You apparently want to upload only image , so the received file must have a width and a height :

Use getImageSize() to get all the required information about the image. If it return false , the file is probably not an image and you can delete it. getImageSize can also give you a mime type , but i don't know if it can be trusted.

2.5- Reprocess image

As suggested by user628405 , reprocessing the image with GD is probably the more secure thing to do.

$img = imagecreatefrompng('vulnerable.png'); 
imagepng($img, 'safe.png');

Obviously it has to be adapted according to the image type. See all the imagecreatefrom* in php documentation.

3- Upload folder In addition of what you have already done :

Make sure your upload folder is not available from the web. Validate the uploaded file then move it to an other folder if needed and rename the file. It will prevent hacker from executing a malicious file (can't execute it if it can't be reached by an url).

Further reading : https://www.owasp.org/index.php/Unrestricted_File_Upload


Need Your Help

saving interactive matplotlib figures

python matplotlib

Is there a way to save a matplotlib figure such that it can be re-opened and have typical interaction restored? (Like the .fig format in matlab?)

How to use PDFBox to create a link that goes to *previous view*?

java pdf pdfbox acrobat

By using PDFBox, it is easy to create a link that goes a particular page or page view by using PDPageDestination. For example, the following code will make a link that goes to page 9:

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.