Security: How to validate image file uploads?

2019-02-17 15:09发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

I'm not sure if it's completely safe but you could use

if( getimagesize($filename) )
  //probably an image