Criminals can fake the content type of the file he's uploading. So, i开发者_JAVA技巧f I receive the file on the server through my page, I cannot just check its MIME type and file extension. Is there any reliable way to check if uploaded file is in fact the JPEG, GIF or PNG? I need to reject all other formats. I could attempt to read the file bit by bit, but what am I looking for? Thanks for any kind of suggestions or ideas!
You could attempt to parse the image inside a try-catch using Bitmap.FromStream(stream)
, with the stream from your uploaded image. If it fails, you know it's not a real image. It's considered coding by exception, but in this case, you're actually looking for an exception.
The easiest way would be to check the header of the input stream and look for specific signatures:
- JPEG: FF D8 in hex
- GIF: first three bytes "GIF"
- PNG: 137 80 78 71 13 10 26 10 in decimal
Example in ASP.NET
bool isValid = false;
char[] header = new char[10];
StreamReader sr = new StreamReader(Request.InputStream);
sr.Read(header, 0, 10);
// check if JPG
if (header[0] == 0xFF && header[1] == 0xD8)
{
isValid = true;
}
// check if GIF
else if (header[0] == 'G' && header[1] == 'I' && header[2] == 'F')
{
isValid = true;
}
// check if PNG
else if (header[0] == 137 && header[1] == 80 && header[2] == 78 && header[3] == 71 && header[4] == 13 && header[5] == 10 && header[6] == 26 && header[7] == 10)
{
isValid = true;
}
of course you'll have to handle the exceptions
You could check if the file has JPEG/GIF/PNG's file signature. But those too could be mimicked by an attacker (though it would probably corrupt any malicious exe). Or you could try using Windows Forms, or what have you, to convert the image data to a bitmap and see if it throws an exception.
You shouldn't need to, as long as you serve it with the MIME type it was uploaded as. The trouble is with Certain Web Browsers (IE) that ignore the MIME type when the data "looks like" something it thinks it knows how to handle. In that case, what you really want to do is mimic IE's file type detection; that's not easy unless you know it looks at the first few bytes.
The "secure" way is to re-encode the image (possibly scaling it down and reducing the quality to reduce file size). This minimizes the amount of control the attacker has over the output. (Of course, people may not appreciate re-encoded images, but most web services do it.)
Additionally, re-encoding the image will generally strip metadata (e.g. the camera serial number), which is good for privacy. This is especially useful when a user thinks they've cropped something out but the image editor leaves it in the thumbnail.
精彩评论