PHP security exploit with GIF images

Manuel Lemos
I usually do not write in this blog about general PHP issues unless it is somehow related with the PHPClasses site.

However, this time I feel that I should use the fact that new blog posts here gets great exposure, as they are notified by e-mail to over 220,000 PHP developers. So I am writing this because it is very important to spread the word about this PHP security exploits that can used to abuse from sites written by many developers that are not well aware of security issues.

Despite in the PHPClasses site there is a great concern about security, I am not really a security expert. More than anything, I am just passing the word.

The PHP GIF security issue
The problem that was discovered is that you can insert PHP code in the middle of a GIF image. That would not be a problem if it was not for the insecure ways some developers use to serve images upload by their users.

Usually, uploaded files are moved to a given directory. If the site then serves the images directly from that directory and preserve the original file name, the site may be open for security exploits.

For instance, lets say the attacker uploads an image named image.gif.php . The image may be moved to the images directory. If the the Web server is configured as usual to process requests with files .php extension, and the site serves the image with the following URL, the request will execute the PHP code inside the image.
http://www.yoursite.com/images/image.gif.php

Avoiding the problem
The basic solution to avoid this problem is to either serve images only with actual extensions of image files (.gif, .png, .jpeg), or protect the upload directory to avoid direct requests to where the images are located.

Depending on your PHP setup, it may or may not be easy to protect your uploaded images directory. In Apache it can be done using a .htaccess file with lines like this:

<Files images>
deny from all
</Files>


Alternatively you can use other PHP functions to serve image files as images, and so, avoid triggering the execution of PHP scripts embedded in image files like these readfile.

http://www.php.net/readfile

$file = 'image.gif.php';

Header('Content-Type: image/gif');


readfile('images/'.basename($file));



Note the use of basename function to avoid injection of malicious paths. This way, only files from inside the images directory will be served, even if the original file named was forged to steal server sensitive files like /etc/passwd .

Other things you should not do
Usually the getimagesize function is used to verify whether the uploaded file is a valid image.

In this case it would not work because the image can still be valid and have a sequence of bytes that can be interpreted as PHP. It is not wrong to use the getimagesize function. Just be aware that it does not avoid the problem.

Another thing that I have seen people doing is to use the include or require functions to serve images stored on the server this. Obviously, this will trigger the execution of PHP code embedded in the image file.

Checking the file name extension before accepting the upload files would not avoid the security hole opened by using include or require to serve the image file on the server side directory. Always use readfile or equivalent to serve the images.


More information
You may learn more about this security issue.

http://isc.sans.org/diary.html?storyid=2997

http://isc.sans.org/diary.html?storyid=3003

I read about it first here:

http://myspaceinfosec.blogspot.com/2007/06/malicous-php-code ...

Finally, in case you are wondering, the PHPClasses site is not affected by these problems because it makes sure that any uploaded files are served via PHP scripts. Those scripts use fopen and fread functions to serve the files.

Actually the site even uses a separate domain to avoid eventual cross-site scripting exploits that could be tried by uploading forged HTML or Flash files. This was explained

http://www.phpclasses.org/blog/post/55-Improved-browsing-and ...

There is a more recent article about defensive programming practices that also provide good advice, specifically about processing external systems data properly.

http://www.phpclasses.org/blog/post/65-8-defensive-programmi ...

If you still have questions or comments, feel free to post a comment about this article.