ASP.NET文件上传:如何确保上传的文件真的是JPEG?

时间:2011-06-29 20:49:42

标签: asp.net security

犯罪分子可以伪造他上传的文件的内容类型。所以,如果我通过我的页面在服务器上收到文件,我不能只检查它的MIME类型和文件扩展名。有没有可靠的方法来检查上传的文件实际上是JPEG,GIF还是PNG?我需要拒绝所有其他格式。我可以尝试一点一点地读取文件,但我在寻找什么?感谢您提出任何建议或想法!

4 个答案:

答案 0 :(得分:6)

您可以使用Bitmap.FromStream(stream)尝试使用上传图片中的流来解析try-catch中的图像。如果它失败了,你知道它不是真实的形象。它被认为是异常编码,但在这种情况下,你实际上是在寻找异常。

答案 1 :(得分:5)

最简单的方法是检查输入流的标题并查找特定的签名:

  • JPEG:FF D8(十六进制)
  • GIF:前三个字节“GIF”
  • PNG:137 80 78 71 13 10 26 10十进制

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;
        }

当然你必须处理例外

答案 2 :(得分:3)

您可以检查文件是否包含JPEG / GIF / PNG file signature。但是那些也可以被攻击者模仿(虽然它可能会破坏任何恶意exe)。或者您可以尝试使用Windows窗体或者您有什么将图像数据转换为位图,看看它是否会引发异常。

答案 3 :(得分:2)

您不需要,只要您使用上传的MIME类型提供服务即可。麻烦在于某些Web浏览器(IE)在数据“看起来像”它认为知道如何处理的东西时忽略MIME类型。在这种情况下,你真正想做的是模仿IE的文件类型检测;除非你知道它会查看前几个字节,否则这并不容易。

“安全”方式是重新编码图像(可能将其缩小并降低质量以减小文件大小)。这最大限度地减少了攻击者对输出的控制量。 (当然,人们可能不会欣赏重新编码的图像,但大多数网络服务都会这样做。)

另外,重新编码图像通常会剥离元数据(例如相机序列号),这有利于隐私。当用户认为他们已裁掉某些内容但the image editor leaves it in the thumbnail时,此功能特别有用。