34

I have a web page that has the file upload component to upload the allowed document types only to my system (images only). I don't want to use the regular expression to determine the file type and using the extension.

Please let me know if there is any other means of determining file types in C#.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
Yagya Sharma
  • 427
  • 1
  • 5
  • 16
  • 5
    You should be able to get some information from the content-type information in the request – Peter Ritchie Jul 18 '12 at 18:08
  • 1
    I'd be picky in the number of image formats you accept, and only use a few for which you know the decompressor is exploit free. –  Jul 18 '12 at 18:17

8 Answers8

42

I've just converted my VB.NET class to C# to detect mime types. They will be identified by a mix of sniffing the first 256 Bytes of a file(urlmon.dll - f.e. used by internet explorer) and a set of known types.

You can also use it to check if the file is what it pretends to be(if the extension matches the type).

// check whether or not the uploaded file is an image:
var contentType = MimeTypes.GetContentType(FileUpload1.PostedFile.FileName);
if(contentType.StartsWith("image"))
{
    // do something with the image ...
}

Here's the class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.IO;

public class MimeTypes
{
    private static List<string> knownTypes;

    private static Dictionary<string, string> mimeTypes;

    [DllImport("urlmon.dll", CharSet = CharSet.Auto)]
    private static extern UInt32 FindMimeFromData(
        UInt32 pBC, [MarshalAs(UnmanagedType.LPStr)]
        string pwzUrl, [MarshalAs(UnmanagedType.LPArray)]
        byte[] pBuffer, UInt32 cbSize, [MarshalAs(UnmanagedType.LPStr)]
        string pwzMimeProposed, UInt32 dwMimeFlags, ref UInt32 ppwzMimeOut, UInt32 dwReserverd
    );

    public static string GetContentType(string fileName)
    {
        if (knownTypes == null || mimeTypes == null)
            InitializeMimeTypeLists();
        string contentType = "";
        string extension = System.IO.Path.GetExtension(fileName).Replace(".", "").ToLower();
        mimeTypes.TryGetValue(extension, out contentType);
        if (string.IsNullOrEmpty(contentType) || knownTypes.Contains(contentType))
        {
            string headerType = ScanFileForMimeType(fileName);
            if (headerType != "application/octet-stream" || string.IsNullOrEmpty(contentType))
                contentType = headerType;
        }
        return contentType;
    }

    private static string ScanFileForMimeType(string fileName)
    {
        try
        {
            byte[] buffer = new byte[256];
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                int readLength = Convert.ToInt32(Math.Min(256, fs.Length));
                fs.Read(buffer, 0, readLength);
            }

            UInt32 mimeType = default(UInt32);
            FindMimeFromData(0, null, buffer, 256, null, 0, ref mimeType, 0);
            IntPtr mimeTypePtr = new IntPtr(mimeType);
            string mime = Marshal.PtrToStringUni(mimeTypePtr);
            Marshal.FreeCoTaskMem(mimeTypePtr);
            if (string.IsNullOrEmpty(mime))
                mime = "application/octet-stream";
            return mime;
        } catch (Exception ex)
        {
            return "application/octet-stream";
        }
    }

    private static void InitializeMimeTypeLists()
    {
        knownTypes = new string[] {
        "text/plain",
        "text/html",
        "text/xml",
        "text/richtext",
        "text/scriptlet",
        "audio/x-aiff",
        "audio/basic",
        "audio/mid",
        "audio/wav",
        "image/gif",
        "image/jpeg",
        "image/pjpeg",
        "image/png",
        "image/x-png",
        "image/tiff",
        "image/bmp",
        "image/x-xbitmap",
        "image/x-jg",
        "image/x-emf",
        "image/x-wmf",
        "video/avi",
        "video/mpeg",
        "application/octet-stream",
        "application/postscript",
        "application/base64",
        "application/macbinhex40",
        "application/pdf",
        "application/xml",
        "application/atom+xml",
        "application/rss+xml",
        "application/x-compressed",
        "application/x-zip-compressed",
        "application/x-gzip-compressed",
        "application/java",
        "application/x-msdownload"
    }.ToList();

        mimeTypes = new Dictionary<string, string>();
        mimeTypes.Add("3dm", "x-world/x-3dmf");
        mimeTypes.Add("3dmf", "x-world/x-3dmf");
        mimeTypes.Add("a", "application/octet-stream");
        mimeTypes.Add("aab", "application/x-authorware-bin");
        mimeTypes.Add("aam", "application/x-authorware-map");
        mimeTypes.Add("aas", "application/x-authorware-seg");
        mimeTypes.Add("abc", "text/vnd.abc");
        mimeTypes.Add("acgi", "text/html");
        mimeTypes.Add("afl", "video/animaflex");
        mimeTypes.Add("ai", "application/postscript");
        mimeTypes.Add("aif", "audio/aiff");
        mimeTypes.Add("aifc", "audio/aiff");
        mimeTypes.Add("aiff", "audio/aiff");
        mimeTypes.Add("aim", "application/x-aim");
        mimeTypes.Add("aip", "text/x-audiosoft-intra");
        mimeTypes.Add("ani", "application/x-navi-animation");
        mimeTypes.Add("aos", "application/x-nokia-9000-communicator-add-on-software");
        mimeTypes.Add("aps", "application/mime");
        mimeTypes.Add("arc", "application/octet-stream");
        mimeTypes.Add("arj", "application/arj");
        mimeTypes.Add("art", "image/x-jg");
        mimeTypes.Add("asf", "video/x-ms-asf");
        mimeTypes.Add("asm", "text/x-asm");
        mimeTypes.Add("asp", "text/asp");
        mimeTypes.Add("asx", "application/x-mplayer2");
        mimeTypes.Add("au", "audio/basic");
        mimeTypes.Add("avi", "video/avi");
        mimeTypes.Add("avs", "video/avs-video");
        mimeTypes.Add("bcpio", "application/x-bcpio");
        mimeTypes.Add("bin", "application/octet-stream");
        mimeTypes.Add("bm", "image/bmp");
        mimeTypes.Add("bmp", "image/bmp");
        mimeTypes.Add("boo", "application/book");
        mimeTypes.Add("book", "application/book");
        mimeTypes.Add("boz", "application/x-bzip2");
        mimeTypes.Add("bsh", "application/x-bsh");
        mimeTypes.Add("bz", "application/x-bzip");
        mimeTypes.Add("bz2", "application/x-bzip2");
        mimeTypes.Add("c", "text/plain");
        mimeTypes.Add("c++", "text/plain");
        mimeTypes.Add("cat", "application/vnd.ms-pki.seccat");
        mimeTypes.Add("cc", "text/plain");
        mimeTypes.Add("ccad", "application/clariscad");
        mimeTypes.Add("cco", "application/x-cocoa");
        mimeTypes.Add("cdf", "application/cdf");
        mimeTypes.Add("cer", "application/pkix-cert");
        mimeTypes.Add("cha", "application/x-chat");
        mimeTypes.Add("chat", "application/x-chat");
        mimeTypes.Add("class", "application/java");
        mimeTypes.Add("com", "application/octet-stream");
        mimeTypes.Add("conf", "text/plain");
        mimeTypes.Add("cpio", "application/x-cpio");
        mimeTypes.Add("cpp", "text/x-c");
        mimeTypes.Add("cpt", "application/x-cpt");
        mimeTypes.Add("crl", "application/pkcs-crl");
        mimeTypes.Add("css", "text/css");
        mimeTypes.Add("def", "text/plain");
        mimeTypes.Add("der", "application/x-x509-ca-cert");
        mimeTypes.Add("dif", "video/x-dv");
        mimeTypes.Add("dir", "application/x-director");
        mimeTypes.Add("dl", "video/dl");
        mimeTypes.Add("doc", "application/msword");
        mimeTypes.Add("dot", "application/msword");
        mimeTypes.Add("dp", "application/commonground");
        mimeTypes.Add("drw", "application/drafting");
        mimeTypes.Add("dump", "application/octet-stream");
        mimeTypes.Add("dv", "video/x-dv");
        mimeTypes.Add("dvi", "application/x-dvi");
        mimeTypes.Add("dwf", "drawing/x-dwf (old)");
        mimeTypes.Add("dwg", "application/acad");
        mimeTypes.Add("dxf", "application/dxf");
        mimeTypes.Add("eps", "application/postscript");
        mimeTypes.Add("es", "application/x-esrehber");
        mimeTypes.Add("etx", "text/x-setext");
        mimeTypes.Add("evy", "application/envoy");
        mimeTypes.Add("exe", "application/octet-stream");
        mimeTypes.Add("f", "text/plain");
        mimeTypes.Add("f90", "text/x-fortran");
        mimeTypes.Add("fdf", "application/vnd.fdf");
        mimeTypes.Add("fif", "image/fif");
        mimeTypes.Add("fli", "video/fli");
        mimeTypes.Add("flv", "video/x-flv");
        mimeTypes.Add("for", "text/x-fortran");
        mimeTypes.Add("fpx", "image/vnd.fpx");
        mimeTypes.Add("g", "text/plain");
        mimeTypes.Add("g3", "image/g3fax");
        mimeTypes.Add("gif", "image/gif");
        mimeTypes.Add("gl", "video/gl");
        mimeTypes.Add("gsd", "audio/x-gsm");
        mimeTypes.Add("gtar", "application/x-gtar");
        mimeTypes.Add("gz", "application/x-compressed");
        mimeTypes.Add("h", "text/plain");
        mimeTypes.Add("help", "application/x-helpfile");
        mimeTypes.Add("hgl", "application/vnd.hp-hpgl");
        mimeTypes.Add("hh", "text/plain");
        mimeTypes.Add("hlp", "application/x-winhelp");
        mimeTypes.Add("htc", "text/x-component");
        mimeTypes.Add("htm", "text/html");
        mimeTypes.Add("html", "text/html");
        mimeTypes.Add("htmls", "text/html");
        mimeTypes.Add("htt", "text/webviewhtml");
        mimeTypes.Add("htx", "text/html");
        mimeTypes.Add("ice", "x-conference/x-cooltalk");
        mimeTypes.Add("ico", "image/x-icon");
        mimeTypes.Add("idc", "text/plain");
        mimeTypes.Add("ief", "image/ief");
        mimeTypes.Add("iefs", "image/ief");
        mimeTypes.Add("iges", "application/iges");
        mimeTypes.Add("igs", "application/iges");
        mimeTypes.Add("ima", "application/x-ima");
        mimeTypes.Add("imap", "application/x-httpd-imap");
        mimeTypes.Add("inf", "application/inf");
        mimeTypes.Add("ins", "application/x-internett-signup");
        mimeTypes.Add("ip", "application/x-ip2");
        mimeTypes.Add("isu", "video/x-isvideo");
        mimeTypes.Add("it", "audio/it");
        mimeTypes.Add("iv", "application/x-inventor");
        mimeTypes.Add("ivr", "i-world/i-vrml");
        mimeTypes.Add("ivy", "application/x-livescreen");
        mimeTypes.Add("jam", "audio/x-jam");
        mimeTypes.Add("jav", "text/plain");
        mimeTypes.Add("java", "text/plain");
        mimeTypes.Add("jcm", "application/x-java-commerce");
        mimeTypes.Add("jfif", "image/jpeg");
        mimeTypes.Add("jfif-tbnl", "image/jpeg");
        mimeTypes.Add("jpe", "image/jpeg");
        mimeTypes.Add("jpeg", "image/jpeg");
        mimeTypes.Add("jpg", "image/jpeg");
        mimeTypes.Add("jps", "image/x-jps");
        mimeTypes.Add("js", "application/x-javascript");
        mimeTypes.Add("jut", "image/jutvision");
        mimeTypes.Add("kar", "audio/midi");
        mimeTypes.Add("ksh", "application/x-ksh");
        mimeTypes.Add("la", "audio/nspaudio");
        mimeTypes.Add("lam", "audio/x-liveaudio");
        mimeTypes.Add("latex", "application/x-latex");
        mimeTypes.Add("lha", "application/lha");
        mimeTypes.Add("lhx", "application/octet-stream");
        mimeTypes.Add("list", "text/plain");
        mimeTypes.Add("lma", "audio/nspaudio");
        mimeTypes.Add("log", "text/plain");
        mimeTypes.Add("lsp", "application/x-lisp");
        mimeTypes.Add("lst", "text/plain");
        mimeTypes.Add("lsx", "text/x-la-asf");
        mimeTypes.Add("ltx", "application/x-latex");
        mimeTypes.Add("lzh", "application/octet-stream");
        mimeTypes.Add("lzx", "application/lzx");
        mimeTypes.Add("m", "text/plain");
        mimeTypes.Add("m1v", "video/mpeg");
        mimeTypes.Add("m2a", "audio/mpeg");
        mimeTypes.Add("m2v", "video/mpeg");
        mimeTypes.Add("m3u", "audio/x-mpequrl");
        mimeTypes.Add("man", "application/x-troff-man");
        mimeTypes.Add("map", "application/x-navimap");
        mimeTypes.Add("mar", "text/plain");
        mimeTypes.Add("mbd", "application/mbedlet");
        mimeTypes.Add("mc$", "application/x-magic-cap-package-1.0");
        mimeTypes.Add("mcd", "application/mcad");
        mimeTypes.Add("mcf", "image/vasa");
        mimeTypes.Add("mcp", "application/netmc");
        mimeTypes.Add("me", "application/x-troff-me");
        mimeTypes.Add("mht", "message/rfc822");
        mimeTypes.Add("mhtml", "message/rfc822");
        mimeTypes.Add("mid", "audio/midi");
        mimeTypes.Add("midi", "audio/midi");
        mimeTypes.Add("mif", "application/x-frame");
        mimeTypes.Add("mime", "message/rfc822");
        mimeTypes.Add("mjf", "audio/x-vnd.audioexplosion.mjuicemediafile");
        mimeTypes.Add("mjpg", "video/x-motion-jpeg");
        mimeTypes.Add("mm", "application/base64");
        mimeTypes.Add("mme", "application/base64");
        mimeTypes.Add("mod", "audio/mod");
        mimeTypes.Add("moov", "video/quicktime");
        mimeTypes.Add("mov", "video/quicktime");
        mimeTypes.Add("movie", "video/x-sgi-movie");
        mimeTypes.Add("mp2", "audio/mpeg");
        mimeTypes.Add("mp3", "audio/mpeg3");
        mimeTypes.Add("mpa", "audio/mpeg");
        mimeTypes.Add("mpc", "application/x-project");
        mimeTypes.Add("mpe", "video/mpeg");
        mimeTypes.Add("mpeg", "video/mpeg");
        mimeTypes.Add("mpg", "video/mpeg");
        mimeTypes.Add("mpga", "audio/mpeg");
        mimeTypes.Add("mpp", "application/vnd.ms-project");
        mimeTypes.Add("mpt", "application/x-project");
        mimeTypes.Add("mpv", "application/x-project");
        mimeTypes.Add("mpx", "application/x-project");
        mimeTypes.Add("mrc", "application/marc");
        mimeTypes.Add("ms", "application/x-troff-ms");
        mimeTypes.Add("mv", "video/x-sgi-movie");
        mimeTypes.Add("my", "audio/make");
        mimeTypes.Add("mzz", "application/x-vnd.audioexplosion.mzz");
        mimeTypes.Add("nap", "image/naplps");
        mimeTypes.Add("naplps", "image/naplps");
        mimeTypes.Add("nc", "application/x-netcdf");
        mimeTypes.Add("ncm", "application/vnd.nokia.configuration-message");
        mimeTypes.Add("nif", "image/x-niff");
        mimeTypes.Add("niff", "image/x-niff");
        mimeTypes.Add("nix", "application/x-mix-transfer");
        mimeTypes.Add("nsc", "application/x-conference");
        mimeTypes.Add("nvd", "application/x-navidoc");
        mimeTypes.Add("o", "application/octet-stream");
        mimeTypes.Add("oda", "application/oda");
        mimeTypes.Add("omc", "application/x-omc");
        mimeTypes.Add("omcd", "application/x-omcdatamaker");
        mimeTypes.Add("omcr", "application/x-omcregerator");
        mimeTypes.Add("p", "text/x-pascal");
        mimeTypes.Add("p10", "application/pkcs10");
        mimeTypes.Add("p12", "application/pkcs-12");
        mimeTypes.Add("p7a", "application/x-pkcs7-signature");
        mimeTypes.Add("p7c", "application/pkcs7-mime");
        mimeTypes.Add("pas", "text/pascal");
        mimeTypes.Add("pbm", "image/x-portable-bitmap");
        mimeTypes.Add("pcl", "application/vnd.hp-pcl");
        mimeTypes.Add("pct", "image/x-pict");
        mimeTypes.Add("pcx", "image/x-pcx");
        mimeTypes.Add("pdf", "application/pdf");
        mimeTypes.Add("pfunk", "audio/make");
        mimeTypes.Add("pgm", "image/x-portable-graymap");
        mimeTypes.Add("pic", "image/pict");
        mimeTypes.Add("pict", "image/pict");
        mimeTypes.Add("pkg", "application/x-newton-compatible-pkg");
        mimeTypes.Add("pko", "application/vnd.ms-pki.pko");
        mimeTypes.Add("pl", "text/plain");
        mimeTypes.Add("plx", "application/x-pixclscript");
        mimeTypes.Add("pm", "image/x-xpixmap");
        mimeTypes.Add("png", "image/png");
        mimeTypes.Add("pnm", "application/x-portable-anymap");
        mimeTypes.Add("pot", "application/mspowerpoint");
        mimeTypes.Add("pov", "model/x-pov");
        mimeTypes.Add("ppa", "application/vnd.ms-powerpoint");
        mimeTypes.Add("ppm", "image/x-portable-pixmap");
        mimeTypes.Add("pps", "application/mspowerpoint");
        mimeTypes.Add("ppt", "application/mspowerpoint");
        mimeTypes.Add("ppz", "application/mspowerpoint");
        mimeTypes.Add("pre", "application/x-freelance");
        mimeTypes.Add("prt", "application/pro_eng");
        mimeTypes.Add("ps", "application/postscript");
        mimeTypes.Add("psd", "application/octet-stream");
        mimeTypes.Add("pvu", "paleovu/x-pv");
        mimeTypes.Add("pwz", "application/vnd.ms-powerpoint");
        mimeTypes.Add("py", "text/x-script.phyton");
        mimeTypes.Add("pyc", "applicaiton/x-bytecode.python");
        mimeTypes.Add("qcp", "audio/vnd.qcelp");
        mimeTypes.Add("qd3", "x-world/x-3dmf");
        mimeTypes.Add("qd3d", "x-world/x-3dmf");
        mimeTypes.Add("qif", "image/x-quicktime");
        mimeTypes.Add("qt", "video/quicktime");
        mimeTypes.Add("qtc", "video/x-qtc");
        mimeTypes.Add("qti", "image/x-quicktime");
        mimeTypes.Add("qtif", "image/x-quicktime");
        mimeTypes.Add("ra", "audio/x-pn-realaudio");
        mimeTypes.Add("ram", "audio/x-pn-realaudio");
        mimeTypes.Add("ras", "application/x-cmu-raster");
        mimeTypes.Add("rast", "image/cmu-raster");
        mimeTypes.Add("rexx", "text/x-script.rexx");
        mimeTypes.Add("rf", "image/vnd.rn-realflash");
        mimeTypes.Add("rgb", "image/x-rgb");
        mimeTypes.Add("rm", "application/vnd.rn-realmedia");
        mimeTypes.Add("rmi", "audio/mid");
        mimeTypes.Add("rmm", "audio/x-pn-realaudio");
        mimeTypes.Add("rmp", "audio/x-pn-realaudio");
        mimeTypes.Add("rng", "application/ringing-tones");
        mimeTypes.Add("rnx", "application/vnd.rn-realplayer");
        mimeTypes.Add("roff", "application/x-troff");
        mimeTypes.Add("rp", "image/vnd.rn-realpix");
        mimeTypes.Add("rpm", "audio/x-pn-realaudio-plugin");
        mimeTypes.Add("rt", "text/richtext");
        mimeTypes.Add("rtf", "text/richtext");
        mimeTypes.Add("rtx", "application/rtf");
        mimeTypes.Add("rv", "video/vnd.rn-realvideo");
        mimeTypes.Add("s", "text/x-asm");
        mimeTypes.Add("s3m", "audio/s3m");
        mimeTypes.Add("saveme", "application/octet-stream");
        mimeTypes.Add("sbk", "application/x-tbook");
        mimeTypes.Add("scm", "application/x-lotusscreencam");
        mimeTypes.Add("sdml", "text/plain");
        mimeTypes.Add("sdp", "application/sdp");
        mimeTypes.Add("sdr", "application/sounder");
        mimeTypes.Add("sea", "application/sea");
        mimeTypes.Add("set", "application/set");
        mimeTypes.Add("sgm", "text/sgml");
        mimeTypes.Add("sgml", "text/sgml");
        mimeTypes.Add("sh", "application/x-bsh");
        mimeTypes.Add("shtml", "text/html");
        mimeTypes.Add("sid", "audio/x-psid");
        mimeTypes.Add("sit", "application/x-sit");
        mimeTypes.Add("skd", "application/x-koan");
        mimeTypes.Add("skm", "application/x-koan");
        mimeTypes.Add("skp", "application/x-koan");
        mimeTypes.Add("skt", "application/x-koan");
        mimeTypes.Add("sl", "application/x-seelogo");
        mimeTypes.Add("smi", "application/smil");
        mimeTypes.Add("smil", "application/smil");
        mimeTypes.Add("snd", "audio/basic");
        mimeTypes.Add("sol", "application/solids");
        mimeTypes.Add("spc", "application/x-pkcs7-certificates");
        mimeTypes.Add("spl", "application/futuresplash");
        mimeTypes.Add("spr", "application/x-sprite");
        mimeTypes.Add("sprite", "application/x-sprite");
        mimeTypes.Add("src", "application/x-wais-source");
        mimeTypes.Add("ssi", "text/x-server-parsed-html");
        mimeTypes.Add("ssm", "application/streamingmedia");
        mimeTypes.Add("sst", "application/vnd.ms-pki.certstore");
        mimeTypes.Add("step", "application/step");
        mimeTypes.Add("stl", "application/sla");
        mimeTypes.Add("stp", "application/step");
        mimeTypes.Add("sv4cpio", "application/x-sv4cpio");
        mimeTypes.Add("sv4crc", "application/x-sv4crc");
        mimeTypes.Add("svf", "image/vnd.dwg");
        mimeTypes.Add("svr", "application/x-world");
        mimeTypes.Add("swf", "application/x-shockwave-flash");
        mimeTypes.Add("t", "application/x-troff");
        mimeTypes.Add("talk", "text/x-speech");
        mimeTypes.Add("tar", "application/x-tar");
        mimeTypes.Add("tbk", "application/toolbook");
        mimeTypes.Add("tcl", "application/x-tcl");
        mimeTypes.Add("tcsh", "text/x-script.tcsh");
        mimeTypes.Add("tex", "application/x-tex");
        mimeTypes.Add("texi", "application/x-texinfo");
        mimeTypes.Add("texinfo", "application/x-texinfo");
        mimeTypes.Add("text", "text/plain");
        mimeTypes.Add("tgz", "application/x-compressed");
        mimeTypes.Add("tif", "image/tiff");
        mimeTypes.Add("tr", "application/x-troff");
        mimeTypes.Add("tsi", "audio/tsp-audio");
        mimeTypes.Add("tsp", "audio/tsplayer");
        mimeTypes.Add("tsv", "text/tab-separated-values");
        mimeTypes.Add("turbot", "image/florian");
        mimeTypes.Add("txt", "text/plain");
        mimeTypes.Add("uil", "text/x-uil");
        mimeTypes.Add("uni", "text/uri-list");
        mimeTypes.Add("unis", "text/uri-list");
        mimeTypes.Add("unv", "application/i-deas");
        mimeTypes.Add("uri", "text/uri-list");
        mimeTypes.Add("uris", "text/uri-list");
        mimeTypes.Add("ustar", "application/x-ustar");
        mimeTypes.Add("uu", "application/octet-stream");
        mimeTypes.Add("vcd", "application/x-cdlink");
        mimeTypes.Add("vcs", "text/x-vcalendar");
        mimeTypes.Add("vda", "application/vda");
        mimeTypes.Add("vdo", "video/vdo");
        mimeTypes.Add("vew", "application/groupwise");
        mimeTypes.Add("viv", "video/vivo");
        mimeTypes.Add("vivo", "video/vivo");
        mimeTypes.Add("vmd", "application/vocaltec-media-desc");
        mimeTypes.Add("vmf", "application/vocaltec-media-file");
        mimeTypes.Add("voc", "audio/voc");
        mimeTypes.Add("vos", "video/vosaic");
        mimeTypes.Add("vox", "audio/voxware");
        mimeTypes.Add("vqe", "audio/x-twinvq-plugin");
        mimeTypes.Add("vqf", "audio/x-twinvq");
        mimeTypes.Add("vql", "audio/x-twinvq-plugin");
        mimeTypes.Add("vrml", "application/x-vrml");
        mimeTypes.Add("vrt", "x-world/x-vrt");
        mimeTypes.Add("vsd", "application/x-visio");
        mimeTypes.Add("vst", "application/x-visio");
        mimeTypes.Add("vsw", "application/x-visio");
        mimeTypes.Add("w60", "application/wordperfect6.0");
        mimeTypes.Add("w61", "application/wordperfect6.1");
        mimeTypes.Add("w6w", "application/msword");
        mimeTypes.Add("wav", "audio/wav");
        mimeTypes.Add("wb1", "application/x-qpro");
        mimeTypes.Add("wbmp", "image/vnd.wap.wbmp");
        mimeTypes.Add("web", "application/vnd.xara");
        mimeTypes.Add("wiz", "application/msword");
        mimeTypes.Add("wk1", "application/x-123");
        mimeTypes.Add("wmf", "windows/metafile");
        mimeTypes.Add("wml", "text/vnd.wap.wml");
        mimeTypes.Add("wmlc", "application/vnd.wap.wmlc");
        mimeTypes.Add("wmls", "text/vnd.wap.wmlscript");
        mimeTypes.Add("wmlsc", "application/vnd.wap.wmlscriptc");
        mimeTypes.Add("word", "application/msword");
        mimeTypes.Add("wp", "application/wordperfect");
        mimeTypes.Add("wp5", "application/wordperfect");
        mimeTypes.Add("wp6", "application/wordperfect");
        mimeTypes.Add("wpd", "application/wordperfect");
        mimeTypes.Add("wq1", "application/x-lotus");
        mimeTypes.Add("wri", "application/mswrite");
        mimeTypes.Add("wrl", "application/x-world");
        mimeTypes.Add("wrz", "model/vrml");
        mimeTypes.Add("wsc", "text/scriplet");
        mimeTypes.Add("wsrc", "application/x-wais-source");
        mimeTypes.Add("wtk", "application/x-wintalk");
        mimeTypes.Add("xbm", "image/x-xbitmap");
        mimeTypes.Add("xdr", "video/x-amt-demorun");
        mimeTypes.Add("xgz", "xgl/drawing");
        mimeTypes.Add("xif", "image/vnd.xiff");
        mimeTypes.Add("xl", "application/excel");
        mimeTypes.Add("xla", "application/excel");
        mimeTypes.Add("xlb", "application/excel");
        mimeTypes.Add("xlc", "application/excel");
        mimeTypes.Add("xld", "application/excel");
        mimeTypes.Add("xlk", "application/excel");
        mimeTypes.Add("xll", "application/excel");
        mimeTypes.Add("xlm", "application/excel");
        mimeTypes.Add("xls", "application/excel");
        mimeTypes.Add("xlsx", "application/excel");
        mimeTypes.Add("xlt", "application/excel");
        mimeTypes.Add("xlv", "application/excel");
        mimeTypes.Add("xlw", "application/excel");
        mimeTypes.Add("xm", "audio/xm");
        mimeTypes.Add("xml", "text/xml");
        mimeTypes.Add("xmz", "xgl/movie");
        mimeTypes.Add("xpix", "application/x-vnd.ls-xpix");
        mimeTypes.Add("xpm", "image/x-xpixmap");
        mimeTypes.Add("x-png", "image/png");
        mimeTypes.Add("xsr", "video/x-amt-showrun");
        mimeTypes.Add("xwd", "image/x-xwd");
        mimeTypes.Add("xyz", "chemical/x-pdb");
        mimeTypes.Add("z", "application/x-compress");
        mimeTypes.Add("zip", "application/x-compressed");
        mimeTypes.Add("zoo", "application/octet-stream");
        mimeTypes.Add("zsh", "text/x-script.zsh");
    }
}

You have to update this list when a mime type is unknown and it is not sufficient to know that it is application/octet-stream. It might suffice to check if an extension is txt but the mime-type is binary data, because that means that this file is not what it pretends to be.


Apart from that it's really easier to use a RegularExpressionValidator.

For example (only jpg-images):

<asp:FileUpload ID="FileUpload1" runat="server" /><br />
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" 
 Text="Upload File" />&nbsp;<br />
<br />
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:RegularExpressionValidator 
 id="RegularExpressionValidator1" runat="server" 
 ErrorMessage="Only jpeg files are allowed!" 
 ValidationExpression="^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))
    +(.jpg|.JPG|.jpeg|.JPEG)$" 
 ControlToValidate="FileUpload1"></asp:RegularExpressionValidator>

In codebehind:

if (FileUpload1.HasFile)
{
    string fileExt = 
       System.IO.Path.GetExtension(FileUpload1.FileName);

    if (fileExt == ".jpeg" || fileExt == ".jpg")
    {
        //do what you want with this image
    }
    else
    {
        Label1.Text = "Only .jpeg files are allowed!";
    }
}
Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • This is excellent !!!.A quick question here. If an exe file is saved as .jpg file by changing the extension, how good is the approach using regular expression. – Yagya Sharma Jul 19 '12 at 05:30
  • @YagyaSharma: The RegularExpression approach just checks the the FileName of the FileUpload control. So there is no "deep-check" at all. But you only have to use my `MimeTypes ` class on serverside. `ScanFileForMimeType` will show that it's not an image type but an `application/octet-stream`. – Tim Schmelter Jul 19 '12 at 07:00
  • I have used the approach of MIME type to implement this functionality. However, as soon as I select the exe file from the file selection dialog, the page is refreshed and comes up with the error message "The page can't be displayed". Any idea why this may be happening. Regards - Yagya – Yagya Sharma Aug 27 '12 at 18:18
  • So are you sure that the file is not simply to large? The default max request size is 4MB. You can change a setting in your web.config to allow larger requests. the maxRequestLength attribute of the httpRuntime element controls that, which you can change in the web.config file. This link shows the schema for the httpRuntime element: http://msdn2.microsoft.com/en-us/library/e1f13641(VS.80).aspx – Tim Schmelter Aug 27 '12 at 20:48
  • You have a valid point. Let me try again with the smaller size and see how it goes. – Yagya Sharma Aug 28 '12 at 08:55
  • Hi - Sorry for the delayed response. In order to address this, we had a check of the file size to be uploaded. However, the check is failing. Our requirement is that maximum file size to be allowed is 1 MB. We have increased the input request size to be 10 MB. Since we don't have a direct control on how big the file end use may attempt to upload to our system. The failure is occuring when try to upload a file that is exe in nature and grater than 10 MB. We get the page that shows the error message "The page can't be displayed". Any idea how to address this, specifically file size validation. – Yagya Sharma Sep 20 '12 at 16:40
  • 1
    This [blog](http://webandlife.blogspot.com/2012/11/google-is-your-alcoholic-friend.html) talks about some issues with the urlmon method and gives remedial code. He's not very good at copy/paste it seems but his refactoring has some tweaks to make it safer (as claimed by author). – Mrchief Aug 01 '14 at 15:03
  • Although great, the mime type is not always accurate. This library "TridLib" and its sample codes shows a better way to get the mime type - http://mark0.net/code-tridlib-e.html – Akshay Raut May 23 '18 at 19:49
7

It's never a good idea to write your code like that:

string fileExt = System.IO.Path.GetExtension(FileUpload1.FileName);

if (fileExt == ".jpeg" || fileExt == ".jpg")
{
    //do what you want with this image
}

The reason of that is because it will give you the extension from the filename. Lets assume that the user is smart enough to change the filename from foo.exe to foo.png and upload it. In this code sample validation will be passed and this is bad for you.

The only appropriate way to identify file type is by checking it magic bytes. According to Wikipedia this term ("magic numbers") was used for a specific set of 2-byte identifiers at the beginnings of files, but since any binary sequence can be regarded as a number, any feature of a file format which uniquely distinguishes it can be used for identification. This approach offers better guarantees that the format will be identified correctly, and can often determine more precise information about the file. Reference to original post.

Because of that I had the same problem a year ago and I created a library that can help you with that scenario. It's easy to use and with few lines of code you will be safe.

Dharman
  • 30,962
  • 25
  • 85
  • 135
5

There is a helper class in .NET for that, called Path. What you need is

Path.GetExtension();

It is located in the System.IO namespace.

Robert
  • 1,658
  • 16
  • 26
  • 3
    Also Peter Ritchie is right, you should be able to get MIME types, but i'm not exactly sure about the right way to do that. – Robert Jul 18 '12 at 18:15
  • 20
    I can upload an exe easily with an extension 'jpg' or 'txt'. – Tim Schmelter Jul 18 '12 at 18:58
  • AFAIK protection from wrapped executables is a virus-protection/firewall problem, and not the job of the program itself. But yet again, I'm not an expert on the topic. – Robert Jul 18 '12 at 20:07
  • Thank you so much for your assistance. The reason I was trying to go deeper was that recently we had an attack on our site. The intruder used the file upload functionality to hack the system. We have disabled this feature for a while. However, we plan to use the fileupload feature again after having a concrete solution in place. Appreciate your asistance. Let me try running the above code and see how well it goes. Best Regards – Yagya Sharma Jul 19 '12 at 05:39
  • @timschmelter Is that a problem? – Ian Warburton Apr 18 '20 at 03:48
  • @timschnelter It’s not apparent from that comment that the vulnerability was what you mentioned. – Ian Warburton Apr 18 '20 at 14:03
  • @IanWarburton This is definately a security risk. Also the file extension is not reliable. Ppl save files with wrong all the time. If you want to know the type of data you've received, you need to read the file header. Current example: We implementet some legacy library to prepare Images for a Webshop. But the library only supports BMP and Jpeg. So we limited the upload to those types. (its an ERP software so only employees can access it- no security concerns) - So 2 Months into using it and the smart guys at sales started renaming zip- and msg-files to jpeg.. – Stefan Lippeck Oct 30 '20 at 07:33
  • @StefanLippeck What's the risk? – Ian Warburton Oct 30 '20 at 12:30
  • @IanWarburton depends on your environment. for example, one could upload malicious code to a website. What kind of code works highly depends on the security issues (known and unknown) of the server, the interpreter etc. Back in the day there where a lot of hacker groups uploading scrips in files that installed illegal FTP server on Websites for example. - And yes, depending on your local laws, this could make you liable for the actions that are hackers execute originating from your machine. – Stefan Lippeck Oct 30 '20 at 15:36
  • @IanWarburton if your server is poorly configured a malicious hacker can inherit the access rights of the service youre handling the upload with, which is usually a system account - meaning very close to root. – Stefan Lippeck Oct 30 '20 at 15:40
  • The question specifically says it does not want to use the file extension – StayOnTarget Oct 05 '22 at 12:30
4

you can use Myrmec to identify the file type, this library use the file byte head. this library avaliable on nuget "Myrmec",and this is the repo, myrmec also support mime type,you can try it. the code will like this :

// create a sniffer instance.
Sniffer sniffer = new Sniffer();

// populate with mata data.
sniffer.Populate(FileTypes.CommonFileTypes);

// get file head byte, may be 20 bytes enough.
byte[] fileHead = ReadFileHead();

// start match.
List<string> results = sniffer.Match(fileHead);
RocketRobin
  • 221
  • 2
  • 5
3

Saw an example that was along the lines of this. Should point you in the right direction. From msdn site.

string fileName = @"C:\mydir.old\myfile.ext";
string path = @"C:\mydir.old\";
string extension;

extension = Path.GetExtension(fileName);
Console.WriteLine("GetExtension('{0}') returns '{1}'", 
fileName, extension);

extension = Path.GetExtension(path);
Console.WriteLine("GetExtension('{0}') returns '{1}'", 
path, extension);

// This code produces output similar to the following:
//
// GetExtension('C:\mydir.old\myfile.ext') returns '.ext'
// GetExtension('C:\mydir.old\') returns ''
Adam
  • 3,615
  • 6
  • 32
  • 51
2

It sounds like you're looking for FindMimeFromData. There's a lot of additional info and code in this question.

Community
  • 1
  • 1
Shane Fulmer
  • 7,510
  • 6
  • 35
  • 43
1
        HttpFileCollection hfc = Request.Files;
        for (int i = 0; i < hfc.Count - 1; i++)
        {
            HttpPostedFile hpf = hfc(i);
            if (hpf.ContentType == "image/jpeg")
            {

                //its a jpeg

            }
        }
Eric Robinson
  • 2,025
  • 14
  • 22
  • 3
    All you've done is checked what the file is supposed to be. It could be anything. It's a good first step, but some content inspection is in order. – james.garriss Apr 12 '13 at 16:14
0
  • Use FileExtensionContentTypeProvider()
[HttpGet]
public string Get(string fileName)
{
    var provider = new FileExtensionContentTypeProvider();
    string contentType;
    if(!provider.TryGetContentType(fileName, out contentType))
    {
        contentType = "application/octet-stream";
    }
    return contentType;
}
Dev-lop-er
  • 578
  • 1
  • 7
  • 16