I need to accept image file uploads from the users.
How can I check and be 100% sure that I don't get a malicious file or something?
Check the mime type? Re-draw the image? Anti-virus?
I need to accept image file uploads from the users.
How can I check and be 100% sure that I don't get a malicious file or something?
Check the mime type? Re-draw the image? Anti-virus?
Redraw the image, read it up with GD's imagecreatefromXXX()
and save it back with imageXXX()
This way you can also scale it to more convenient sizes and keep bandwidth consumption in check.
To save on computing power, deny upload to files bigger than a certain limit.
5megs or 10megs should be fine, as limits go.
Keep GD updated, and be wary that (7 years ago, apparently) it used to sport buffer overflows in the handling of PNG images
Alternatively, you could also preprocess uploaded images in background with commands such as ImageMagick's
convert
and such.Last note of warning: on Windo(w)s
convert
is also a command used to format hard disk, so put some effort into removing abiguities if you deploy on that.
If you are concerned about malicious files use an antivirus checker, or better yet, two of them since one might be lagging on a particular new strain.
MIME types can be spoofed, as can using file
.
You could use code to open it, checking to see if all the blocks are the right sizes, but exploits take advantage of flaws in the code used to open the image. You could be opening the door to exploit on your host/server if your code isn't hardened and aware of all the ways it could be exploited - it's almost a chicken and egg situation, so I lean toward trusting a couple antivirus tools more.
I would not go for 100% image type validation, I use simple script to check image type validation
$imgExtension = array('jpg','jpe','jpeg','gif','png');
$image_name = pathinfo($_FILES['image']['name']);
$extension = strtolower($image_name['extension']);
if(in_array($extension,$ImgExtension)){
//process file upload - move_uploaded_file()
}
?>
Still you can also check mime type to make more accurate validation.
I'm not sure if it's completely safe but you could use
if( getimagesize($filename) )
//probably an image