验证上传的文件是否为镜像

本文关键字:是否 镜像 文件 验证 | 更新日期: 2023-09-27 18:14:46

我将在。net Core 1.0.1的新网站上接受用户上传。但是,我只想允许使用图像,而不是任何文件。我如何在。net Core中执行此验证?有没有可能没有System.Drawing,因为它没有实现?

这个答案看起来很有希望,但它最终使用了System.Drawing。检查内容类型和扩展是否足够?


EDIT:接受的答案是我需要的,但我将在这里分享我的实际实现。我在。net Core中这样做,但我很确定相同的代码可以在整个框架中工作。

static bool IsJpeg(Stream stream)
{
    using (var br = new BinaryReader(stream))
    {
        var soi = br.ReadUInt16();
        var marker = br.ReadUInt16();
        return soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
    }
}
static bool IsPng(Stream stream)
{
    using (var br = new BinaryReader(stream))
    {
        var soi = br.ReadUInt64();
        return soi == 0x0a1a0a0d474e5089;
    }
}
static bool IsGif(Stream stream)
{
    using (var br = new BinaryReader(stream))
    {
        var soi = br.ReadUInt32();
        var p2 = br.ReadUInt16();
        return soi == 0x38464947 && (p2 == 0x6137 || p2 == 0x6139);
    }
}

验证上传的文件是否为镜像

仅仅检查文件扩展名是不够的。我可以制作一个ZIP文件,然后将扩展名重命名为.jpg,您会认为这是一个有效的文件。

图像格式的开头确实有"魔法字节",您可以使用它来潜在地识别文件实际上是图像。这里的维基百科条目有一个魔术数字列表,你可以检查。

还要注意,内容类型可以被欺骗。

你有两件事可以做。在原始答案中指定的内容类型,并检查文件的"幻数"。如果有人真的想上传非图像的无用数据,并绕过这两个检查,您可能需要做其他事情。

那么,你有三个已知的保护可以实现:

  1. 文件在白名单上有扩展名吗?(jpg/jpeg/等)
  2. 内容类型是否与白名单上的条目匹配?(图片/jpeg)
  3. 一旦你通过前两步确定了它是哪种文件,魔法数字也匹配吗?