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

4
罪犯可以伪造上传文件的内容类型。因此,如果我通过我的页面在服务器上接收文件,我不能仅检查其MIME类型和文件扩展名。有没有可靠的方法来检查上传的文件是否实际上是JPEG、GIF或PNG?我需要拒绝所有其他格式。我可以尝试逐位读取文件,但我要找什么呢?感谢任何建议或想法!
4个回答

6

您可以尝试使用Bitmap.FromStream(stream)在try-catch中解析上传图像的流。如果失败,说明它不是真正的图像。虽然这被认为是“异常编码”,但在这种情况下,实际上您正在寻找一个异常。


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

当然,您将需要处理异常。

我该如何在ASP.NET中检查头文件? - Kizz

3
您可以检查文件是否具有JPEG/GIF/PNG的文件签名。但是攻击者也可以模仿这些文件签名(尽管这可能会损坏任何恶意exe)。或者您可以尝试使用Windows Forms等工具将图像数据转换为位图,并查看是否会引发异常。

2
只要以上传时的MIME类型提供服务,就不应该需要重新编码图片。问题在于某些网络浏览器(如IE)会忽略MIME类型,而是依据数据“看起来像”自己可以处理的文件类型来处理。在这种情况下,你真正想做的是模仿IE的文件类型检测;除非你知道它查看前几个字节,否则这并不容易。
“安全”的方法是重新编码图像(可能缩小大小和降低质量以减少文件大小)。这将最大程度地减少攻击者对输出的控制。当然,人们可能不喜欢重新编码的图像,但大多数网络服务都这样做。
此外,重新编码图像通常会删除元数据(例如相机序列号),这有助于保护隐私。当用户认为他们已经裁剪掉了某些东西但是图像编辑器在缩略图中仍显示时,这尤其有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接