在C#中上传文件时检查文件格式 [英] File Format check while File upload in C#

查看:109
本文介绍了在C#中上传文件时检查文件格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文件上传时我已经检查了以下内容

While File Upload i have checked the following thing

   if !(strExtension == ".jpg" || strExtension == ".jpeg" || strExtension == ".pdf" || strExtension == ".png")

   Send Error

这很好,

但是我有一个问题,如果有人通过更改扩展名来上传xlsx文件作为jpg,我的上传器不会阻止它,并且文件将被保存,该文件原本是xlsx文件

But i have one issue ,if someone uploads a xlsx file by just changing its extension as jpg my uploader will not obstruct it and the file will be saved which is orginally an xlsx file

如何检查文件来源。

谢谢您的帮助

推荐答案

编辑:只需使用动漫侦探

I使用字节数组序列来确定给定文件的正确MIME类型。与仅查看文件名的文件扩展名相比,这样做的好处是,如果用户要重命名文件以绕过某些文件类型上载限制,则文件名扩展名将无法捕获此文件。另一方面,通过字节数组获取文件签名将阻止这种调皮的行为的发生。

I use byte array sequences to determine the correct MIME type of a given file. The advantage of this over just looking at the file extension of the file name is that if a user were to rename a file to bypass certain file type upload restrictions, the file name extension would fail to catch this. On the other hand, getting the file signature via byte array will stop this mischievous behavior from happening.

这里是C#中的一个示例:

Here is an example in C#:

public class MimeType
{
    private static readonly byte[] BMP = { 66, 77 };
    private static readonly byte[] DOC = { 208, 207, 17, 224, 161, 177, 26, 225 };
    private static readonly byte[] EXE_DLL = { 77, 90 };
    private static readonly byte[] GIF = { 71, 73, 70, 56 };
    private static readonly byte[] ICO = { 0, 0, 1, 0 };
    private static readonly byte[] JPG = { 255, 216, 255 };
    private static readonly byte[] MP3 = { 255, 251, 48 };
    private static readonly byte[] OGG = { 79, 103, 103, 83, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 };
    private static readonly byte[] PDF = { 37, 80, 68, 70, 45, 49, 46 };
    private static readonly byte[] PNG = { 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82 };
    private static readonly byte[] RAR = { 82, 97, 114, 33, 26, 7, 0 };
    private static readonly byte[] SWF = { 70, 87, 83 };
    private static readonly byte[] TIFF = { 73, 73, 42, 0 };
    private static readonly byte[] TORRENT = { 100, 56, 58, 97, 110, 110, 111, 117, 110, 99, 101 };
    private static readonly byte[] TTF = { 0, 1, 0, 0, 0 };
    private static readonly byte[] WAV_AVI = { 82, 73, 70, 70 };
    private static readonly byte[] WMV_WMA = { 48, 38, 178, 117, 142, 102, 207, 17, 166, 217, 0, 170, 0, 98, 206, 108 };
    private static readonly byte[] ZIP_DOCX = { 80, 75, 3, 4 };

    public static string GetMimeType(byte[] file, string fileName)
    {

        string mime = "application/octet-stream"; //DEFAULT UNKNOWN MIME TYPE

        //Ensure that the filename isn't empty or null
        if (string.IsNullOrWhiteSpace(fileName))
        {
            return mime;
        }

        //Get the file extension
        string extension = Path.GetExtension(fileName) == null
                               ? string.Empty
                               : Path.GetExtension(fileName).ToUpper();

        //Get the MIME Type
        if (file.Take(2).SequenceEqual(BMP))
        {
            mime = "image/bmp";
        }
        else if (file.Take(8).SequenceEqual(DOC))
        {
            mime = "application/msword";
        }
        else if (file.Take(2).SequenceEqual(EXE_DLL))
        {
            mime = "application/x-msdownload"; //both use same mime type
        }
        else if (file.Take(4).SequenceEqual(GIF))
        {
            mime = "image/gif";
        }
        else if (file.Take(4).SequenceEqual(ICO))
        {
            mime = "image/x-icon";
        }
        else if (file.Take(3).SequenceEqual(JPG))
        {
            mime = "image/jpeg";
        }
        else if (file.Take(3).SequenceEqual(MP3))
        {
            mime = "audio/mpeg";
        }
        else if (file.Take(14).SequenceEqual(OGG))
        {
            if (extension == ".OGX")
            {
                mime = "application/ogg";
            }
            else if (extension == ".OGA")
            {
                mime = "audio/ogg";
            }
            else
            {
                mime = "video/ogg";
            }
        }
        else if (file.Take(7).SequenceEqual(PDF))
        {
            mime = "application/pdf";
        }
        else if (file.Take(16).SequenceEqual(PNG))
        {
            mime = "image/png";
        }
        else if (file.Take(7).SequenceEqual(RAR))
        {
            mime = "application/x-rar-compressed";
        }
        else if (file.Take(3).SequenceEqual(SWF))
        {
            mime = "application/x-shockwave-flash";
        }
        else if (file.Take(4).SequenceEqual(TIFF))
        {
            mime = "image/tiff";
        }
        else if (file.Take(11).SequenceEqual(TORRENT))
        {
            mime = "application/x-bittorrent";
        }
        else if (file.Take(5).SequenceEqual(TTF))
        {
            mime = "application/x-font-ttf";
        }
        else if (file.Take(4).SequenceEqual(WAV_AVI))
        {
            mime = extension == ".AVI" ? "video/x-msvideo" : "audio/x-wav";
        }
        else if (file.Take(16).SequenceEqual(WMV_WMA))
        {
            mime = extension == ".WMA" ? "audio/x-ms-wma" : "video/x-ms-wmv";
        }
        else if (file.Take(4).SequenceEqual(ZIP_DOCX))
        {
            mime = extension == ".DOCX" ? "application/vnd.openxmlformats-officedocument.wordprocessingml.document" : "application/x-zip-compressed";
        }

        return mime;
    }


}

我处理过的通知DOCX文件类型不同,因为DOCX实际上只是一个ZIP文件。在这种情况下,只要验证了文件扩展名的顺序,我就可以简单地对其进行检查。对于某些人来说,此示例还远远不够完整,但是您可以轻松地添加自己的示例。

Notice I handled DOCX file types differently since DOCX is really just a ZIP file. In this scenario, I simply check the file extension once I verified that it has that sequence. This example is far from complete for some people, but you can easily add your own.

如果要添加更多的MIME类型,则可以获取的字节数组序列从此处。另外,这里是另一个有关文件签名的好资源

If you want to add more MIME types, you can get the byte array sequences of many different file types from here. Also, here is another good resource concerning file signatures.

如果所有其他操作都失败了,我经常会遍历我正在寻找的特定类型的几个文件,并在文件的字节序列中寻找模式。最后,这仍然是基本验证,不能用于100%确定文件类型的证明。

What I do a lot of times if all else fails is step through several files of a particular type that I am looking for and look for a pattern in the byte sequence of the files. In the end, this is still basic verification and cannot be used for 100% proof of determining file types.

这篇关于在C#中上传文件时检查文件格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆