Abusing Django with Evil Avatars
We assess a lot of Django based web applications. Because the Django framework does a great job at trying to be secure by default sometimes we have to get creative.
Background
About a week back I ran into a situation in which I could upload a file to an application and control the filename. In this particular case the file had to be a valid image per the rules of the Django ImageField.is_valid() method. This is not uncommon to see in web applications with avatars and other image uploads. Apps like Django_avatar and Pinax (that uses a slighly older django_avatar I believe) are examples that do not check the file extension and rely on the ImageField validator.
The Exploit
Using exiftool I added a comment field in the images header that does not invalidate the image but will be executed if the file is named with a .php extension. The exiftool command I used to create the below image was
exiftool -comment=”<? phpinfo(); ?>” ngenuity-avatar.jpg
The below image is a non-malicious example that when named with a .php extension will execute phpinfo(); when viewed.
![]()
This was tested on PHP versions 5.2.10 and 5.3.2, Pinax 0.7.1 and django_avatar 1.1a1. I noticed that on 5.3.1 php will not execute the payload properly.
Protection
Just a few thoughts on how to protect against this.
- Chances are if you are using Django you don't need PHP configured to run on your web site. If you do disable parsing of PHP and other server side content in your media directories.
- Do not rely on ImageField validation to protect you. Check file extensions against a whitelist for uploaded media.
- It would be nice to see the Django ImageField updated validate file extensions as well. At the same time it easy and leaves the framework flexible to leave it up to the implementor.