I have a lot of user uploaded content and I want to validate that uploaded image files are not, in fact, malicious scripts. In the Django documentation, it states that ImageField:
"Inherits all attributes and methods from FileField, but also validates that the uploaded object is a valid image."
Is that totally accurate? I've read that compressing or otherwise manipulating an image file is a good validation test. I'm assuming that PIL does something like this....
Will ImageField go a long way toward covering my image upload security?
Another test is with the file command. It checks for the presence of "magic numbers" in the file to determine its type. On my system, the
file
package includeslibmagic
as well as a ctypes-based wrapper/usr/lib64/python2.7/site-packages/magic.py
. It looks like you use it like:(Code from here.)
As to your original question: "Read the Source, Luke."
django/core/files/images.py:
So it looks like it just reads the file 1024 bytes at a time until PIL says it's an image, then stops. This obviously does not integrity-check the entire file, so it really depends on what you mean by "covering my image upload security": illicit data could be appended to an image and passed through your site. Someone could DOS your site by uploading a lot of junk or a really big file. You could be vulnerable to an injection attack if you don't check any uploaded captions or make assumptions about the image's uploaded filename. And so on.
Django validates the image uploaded via form using PIL. See https://code.djangoproject.com/browser/django/trunk/django/forms/fields.py#L519
PIL documentation states the following about verify():
You should also note that ImageField is only validated when uploaded using form. If you save the model your self (e.g. using some kind of download script), the validation is not performed.