Results 1 to 22 of 22

Thread: MIME Type validation based on the actual file

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    MIME Type validation based on the actual file

    Hi all,

    I've got the upload control doing validation of the mime type, but there's a problem with it.

    If I rename an EXE to XLS, the upload control thinks it's an Excel file and goes on its merry way.

    Is there a way to inspect the CONTENTS of the file (maybe just the file header) and validate that the actual file is what it is and not what the extension says it is? I'm using C# in the back end but am open to whatever works

    And just so I understand, if the user DOES change the extension from EXE to XLS, is there any harm in still uploading the file? And what would happen if I tried to open that file (formerly EXE now XLS) when it was served up from my application?

    Thanks,
    Jon

  2. #2
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: MIME Type validation based on the actual file

    Hello,

    The short answer is, on the client side, the only thing that you have to go on is the file name. Once you upload the file, you can inspect the file directly, for instance there is a native PInvoke call that you can do called FindMimeFromData that you can use. In terms of uploading the file, there is an element of risk, but as long as you don't actually execute the file, i.e. Process.Start it for instance, you should be fine. If you do the native check and you find that it is something you don't want, just delete it.

    Gary

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    Hi Gary,

    So I would have to do the file mime type check AFTER the control has saved the file? Then if it's garbage, delete it out?

  4. #4
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: MIME Type validation based on the actual file

    Yes, that would be my understanding. Obviously, you can still do the file extension check on the client, and decide whether to upload the file at all.

    Gary

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    I'm doing an extension check for validation on the client side before saving, so that's not a problem.

    I found some code here that is looking somewhat promising. I renamed an EXE to XLS and actually got a mime type of "application/x-msdownload" when I inspected it, so I may be on the right track. I just need to do a lot more testing Uploading an actual excel file gave me "application/octet-stream"

    Here's what I found:
    Code:
        [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
        private extern static System.UInt32 FindMimeFromData(System.UInt32 pBC,
                                                            [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
                                                            [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
                                                            System.UInt32 cbSize,         
                                                            [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,         
                                                            System.UInt32 dwMimeFlags,         
                                                            out System.UInt32 ppwzMimeOut,         
                                                            System.UInt32 dwReserverd     );
        public string getMimeFromFile(string filename)
        {
            if (!File.Exists(filename))
                throw new FileNotFoundException(filename + " not found");
            byte[] buffer = new byte[256];
            using (FileStream fs = new FileStream(filename, FileMode.Open))
            {
                if (fs.Length >= 256)
                    fs.Read(buffer, 0, 256);
                else
                    fs.Read(buffer, 0, (int)fs.Length);
            }
            try
            {
                System.UInt32 mimetype;
                FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
                System.IntPtr mimeTypePtr = new IntPtr(mimetype);
                string mime = Marshal.PtrToStringUni(mimeTypePtr);
                Marshal.FreeCoTaskMem(mimeTypePtr);
                return mime;
            }
            catch (Exception e)
            {
                return "unknown/unknown";
            }
        }

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    BTW Gary, I found the code because, once again, you nudged me in the right direction Thanks again!

  7. #7
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: MIME Type validation based on the actual file

    Quote Originally Posted by ediguy View Post
    BTW Gary, I found the code because, once again, you nudged me in the right direction Thanks again!
    Not a problem at all, happy to help

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    So I just want to confirm something. Is it possible to do the check for the actual MIME type WHILE the file is uploading as opposed to after it has been uploaded? Maybe using a streamreader to inspect the file as it goes and then if it fails inspection midway through the file, kill the upload and notify the user? I am being told this is possible within java, but I haven't found anything that says you can do it.

    And what's the danger to your server if you DO upload an EXE/BAT/VBS etc then immediately delete it after you inspected the header with the code above? Will the code above activate the script or not? (I don't think it will but I have been known to be wrong often ).

    Just wondering if I am trying to solve somthing that has either been solved or isn't possible.

  9. #9
    Frenzied Member brin351's Avatar
    Join Date
    Mar 2007
    Location
    Land Down Under
    Posts
    1,293

    Re: MIME Type validation based on the actual file

    I would say don't try to inspect the file while it's uploading. The file is being written to memory during the upload process so I wouldn't interupt that process. I guess you take a copy of the first 20KB and play with that but.... thats messy.

    Secondly you don't need to save the file to disk when upload completes, it's in memory so you can test it before saving it. In your testing method refrence the file fromStream/Memory or what ever. If I need to work with uploaded images before saving them I just pass the upload control to that method like below.

    Code:
    sub changeImage(ByVal fileUpload As System.Web.UI.WebControls.FileUpload)
    
    Dim TheImage As System.Drawing.Image = System.Drawing.Image.FromStream(fileUpload.PostedFile.InputStream)
    
    end sub
    The problem with computers is their nature is pure logic. Just once I'd like my computer to do something deluded.

  10. #10
    Frenzied Member brin351's Avatar
    Join Date
    Mar 2007
    Location
    Land Down Under
    Posts
    1,293

    Re: MIME Type validation based on the actual file

    I just looked at my file upload validation and I think your doing things the hard way.

    Code:
    dim mime as string = fileUpload.PostedFile.ContentType
    gets the mime type of the file which you can check against your allowed types. I also test file extentions.

    I'd like to know if changing the file extention changes .contentType..... I don't think so but please correct me if I'm wrong
    The problem with computers is their nature is pure logic. Just once I'd like my computer to do something deluded.

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    Quote Originally Posted by brin351 View Post
    I just looked at my file upload validation and I think your doing things the hard way.

    Code:
    dim mime as string = fileUpload.PostedFile.ContentType
    gets the mime type of the file which you can check against your allowed types. I also test file extentions.

    I'd like to know if changing the file extention changes .contentType..... I don't think so but please correct me if I'm wrong
    I do check the contenttype prior to physically uploading the file. If I rename an EXE or a BAT file to .XLS and check the content type, I am getting a content type for the XLS file.

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    OK I think I have a solution that at least catches whether or not the file is a renamed EXE file. The renamed BAT file is still returning a value that I can't differentiate between a valid value, but I'm working on that somehow.

    I slightly modified the code above as shown below:

    Code:
        public string getMimeFromFile(Stream filename)
        {
            byte[] buffer = new byte[256];
            using (filename) 
            {
                if (filename.Length >= 256)
                    filename.Read(buffer, 0, 256);
                else
                    filename.Read(buffer, 0, (int)filename.Length);
            }
            try
            {
                System.UInt32 mimetype;
                FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
                System.IntPtr mimeTypePtr = new IntPtr(mimetype);
                string mime = Marshal.PtrToStringUni(mimeTypePtr);
                Marshal.FreeCoTaskMem(mimeTypePtr);
                return mime;
            }
            catch (Exception e)
            {
                return "unknown/unknown";
            }
        }
    I call this code during the routine that validates whether or not I should accept the file prior to saving (where I check the dulUploadFile.PostedFile.ContentType.ToString() value and get an incorrect value for the renamed EXE to XLS).

    I can identify that the file is not actually an XLS file IF (and ONLY IF so far ) it's an EXE. Then I can throw an error in my validation so the upload save never occurs.

    Now I just have to figure out how to properly trap for a renamed BAT file, although based on the testing I have done so far with serving up the saved document to a user, I'm not sure it's worth it.

    Also trying to see what Excel/Word scripts would do, but unfortunately I don't have any.

  13. #13

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    OK I found out that code doesn't work at all. What happens is that the HttpStreamReader read ends up clearing out the asp:Upload control data, so that when it writes out using the saveas parameter, the stream is empty and you get a blank file.

    Back to the drawing board

  14. #14
    Frenzied Member brin351's Avatar
    Join Date
    Mar 2007
    Location
    Land Down Under
    Posts
    1,293

    Re: MIME Type validation based on the actual file

    Forgetting passing a stream I found this code to get mime type. works for me

    http://stackoverflow.com/questions/8...load-mime-type
    Last edited by brin351; Apr 12th, 2011 at 08:21 PM.
    The problem with computers is their nature is pure logic. Just once I'd like my computer to do something deluded.

  15. #15

    Thread Starter
    Hyperactive Member
    Join Date
    Dec 2005
    Posts
    323

    Re: MIME Type validation based on the actual file

    Am I correct in thinking that works only after the file has been uploaded?

  16. #16
    Frenzied Member tr333's Avatar
    Join Date
    Nov 2004
    Location
    /dev/st0
    Posts
    1,605

    Re: MIME Type validation based on the actual file

    You can get the file MIME type from JavaScript for browsers that have implemented it. It's part of the HTML5 spec but I believe only Firefox, Safari, and Chrome have currently implemented this feature. Other browsers will have to rely on file extension checking, or checking the MIME type from the server-side after the file has been uploaded.

    https://developer.mozilla.org/en/usi...b_applications

    JavaScript Code:
    1. function validateMyFiles(files) {
    2.     for (var i = 0; i < files.length; i++) {
    3.         var file = files[i];
    4.         if (file.type === undefined)
    5.             return;
    6.        
    7.         // do some other validation here on the MIME type in file.type using regex or similar
    8.     }
    9. }

    You could then call this from onchange() event handler of the <ASP:FileUpload>.
    Code:
    <asp:FileUpload runat="server" id="MyFileUpload" onchange="validateMyFiles(this.files);" />
    CSS layout comes in to the 21st century with flexbox!
    Just another Perl hacker,

  17. #17
    Frenzied Member brin351's Avatar
    Join Date
    Mar 2007
    Location
    Land Down Under
    Posts
    1,293

    Re: MIME Type validation based on the actual file

    I've been considering file validation because file upload is common place these days. I looked at the limitition of FindMimeFromData from urlmon.dll and the "know mime types" don't include application/excel or the variations on it. It's a short list of common mime types for internet explorer.

    http://msdn.microsoft.com/en-us/libr...nown_MimeTypes

    I also noticed FindMimeFromData will also test registry values and I presume some form of excel would need to be installed for a match to occur.

    I was hoping to find a sure fire method for all file types but I was dreaming. Some asp upload products say they can do mime type validation but I wonder how good they actually are.

    All I can think of is to try and read some lines from the excel spredsheet with ado.net or maybe try the Excel Interop DLL if you dont mind that dependancy
    The problem with computers is their nature is pure logic. Just once I'd like my computer to do something deluded.

  18. #18
    ASP.NET Moderator gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: MIME Type validation based on the actual file

    Hello,

    Is the FileUpload control available on your website publically, or is it a member only function? The reason that I ask is, why do you need to validate the file? What is the requirement that makes it necessary?

    Gary

  19. #19
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: MIME Type validation based on the actual file

    See if this helps:
    https://pradeep1210.wordpress.com/20...-content-type/

    I customized it a bit more in my actual implementation, but I hope you would be able to do that part yourself. Let me know if you need any further help.
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  20. #20
    Frenzied Member brin351's Avatar
    Join Date
    Mar 2007
    Location
    Land Down Under
    Posts
    1,293

    Re: MIME Type validation based on the actual file

    Excellent work.

    I had a brief look over your class and can you tell me what is returned if urlmon (findmimefromdata) doesn't get a match.

    From the point of view that the file extention is easy to changed so getting mime from data is the best validation, does it fall back to "application/octet-stream" or the extention mapping if findmimefromdata doesn't get a match.

    For everyones info you can use reflection to get the .net mimetype/extention mappings. I think this is the same as .contentType uses

    Code:
    ''' <summary> 
    ''' This class allows access to the internal MimeMapping-Class in System.Web 
    ''' </summary> 
    Class MimeMappingWrapper
    	Shared getMimeMappingMethod As MethodInfo
    	Shared Sub New()
    		' dirty trick - Assembly.LoadWIthPartialName has been depricated         
    		Dim ass As Assembly = Assembly.LoadWithPartialName("System.Web")
    		Dim t As Type = ass.[GetType]("System.Web.MimeMapping")
    		getMimeMappingMethod = t.GetMethod("GetMimeMapping", BindingFlags.[Static] Or BindingFlags.NonPublic)
    	End Sub
    
    	Public Shared Function GetMimeMapping(fileName As String) As String
    		Return DirectCast(getMimeMappingMethod.Invoke(Nothing, New () {fileName}), String)
    	End Function
    End Class
    The problem with computers is their nature is pure logic. Just once I'd like my computer to do something deluded.

  21. #21
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: MIME Type validation based on the actual file

    Quote Originally Posted by brin351 View Post
    Excellent work.

    I had a brief look over your class and can you tell me what is returned if urlmon (findmimefromdata) doesn't get a match.

    From the point of view that the file extention is easy to changed so getting mime from data is the best validation, does it fall back to "application/octet-stream" or the extention mapping if findmimefromdata doesn't get a match.
    It first tries to get file type from the file contents.
    If that fails, it tries to get the file type from file extension.
    If that too fails, "application/octet-stream" is assumed.
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  22. #22
    Frenzied Member brin351's Avatar
    Join Date
    Mar 2007
    Location
    Land Down Under
    Posts
    1,293

    Re: MIME Type validation based on the actual file

    ok thanks for that. It's a good way to validate standard files being uploaded.
    The problem with computers is their nature is pure logic. Just once I'd like my computer to do something deluded.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width