Solved

Validating file type in file upload

Posted on 2012-03-30
22
632 Views
Last Modified: 2012-04-06
Hi Experts,

I am working on ASP.net2.0 using C#

There is a functionality to upload files. I wanted to validate if user uploads file, then file should be valid type.

I need to validate for MP3 files, If user rename the MP3 file to say with .txt file, user should get an error, that file is not valid type

Please help me how to do this

Regards,
0
Comment
Question by:tia_kamakshi
  • 9
  • 8
  • 2
  • +3
22 Comments
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37790029
0
 
LVL 27

Expert Comment

by:Chinmay Patel
ID: 37790038
Hi tia_kamakshi,

If you are trying to determine by just checking the extesnion, you could do it on clientside itself via JavaScripe.
http://www.codeproject.com/Articles/156981/Check-File-type-at-client-side-jQuery

If you want to do it at server side [but file is uploaded anyways] by just looking at the extensino then
http://stackoverflow.com/questions/5125894/get-file-type-of-request-files-in-asp-net

Let me know if you need more help.

Regards,
Chinmay.
0
 

Author Comment

by:tia_kamakshi
ID: 37790136
Thanks for all your replies.

I am already validating by file extensions. I meant in my orignal question that

"I need to validate for MP3 files, If user rename the MP3 file to say with .txt file, user should get an error, that file is not valid type"

If user rename the file and makes that to txt file, then above solutions will allow user to upload the file.

Here user has uploaded the MP3 file by renaming it to .txt file, I need to validate if file is actual txt file and not MP3.

Our Security department will not pass by validating file using file extensions only. I need only valid files to be uploaded, user should not be able to do any ir-relevant things

Regards,
0
 
LVL 27

Expert Comment

by:Chinmay Patel
ID: 37790148
Hi tia_kamakshi,

I have a question here. The file that is being uploaded is always going to be a text file?

Regards,
Chinmay.
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37790171
you basically have to check the type of file by reading its first few bytes.

Here are the links that will help you achieve this:-
http://stackoverflow.com/questions/2921646/programatically-find-out-a-file-type-by-looking-its-binary-content-possible
http://www.wotsit.org/
0
 

Author Comment

by:tia_kamakshi
ID: 37791092
BuggyCoder
Your both links are not good examples. Not sure if you understood my question well.

Chinmay_Patel
User can upload few file types for example .txt, pdf, .doc, .docx, .xls, .xlsx

We might have to check file mime type etc to solve this. We have a solution for .exe file, if user rename .exe with any file extension say txt, then my code recognise that whether it is really txt or not

But we are not able to fix for .Mp3 file. I have not seen the code yet how .exe things has fixed. The guy working on this has gone for emergency leave and I have to fix this for .mp3 file

Regards,
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37791159
Unfortunately, BuggyCoder's links are exactly what you have to do. Think about it:  does Office check a mime type when it opens a file? No. It looks for the "magic number" (referenced in the previously mentioned links) to tell if the file is a valid file to be opened. The only way to tell that a submitted file is of the type as indicated by the client is to examine the file in the same way that the associated program would. Mime type is not that way.
0
 

Author Comment

by:tia_kamakshi
ID: 37792383
ohh I understand. How do we check this in ASP.net 2.0 using C#.

Also , I am checking following mime types only, then why it is failing in case of mp3 file. I mean if mp3 file extension is renamed (say .txt) then it is not recognising and accepting the file. But when I rename to .exe or some other then it recognise that it is not valid file type


application/msword
application/vnd.ms-word
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/pdf
application/excel
application/x-excel
application/x-msexcel
application/vnd.ms-excel
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application/plain
text/plain
text/html
application/powerpoint
application/mspowerpoint
application/vnd.ms-powerpoint
application/x-mspowerpoint
application/vnd.openxmlformats-officedocument.presentationml.presentation
application/rtf
application/x-rtf
text/richtext
text/rtf
image/bmp
image/x-windows-bmp
image/jpeg
image/pjpeg
image/gif

Please suggest

Regards,
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37792399
Mime type check is applied by the server looking at the content-type header, so whatever you set in there it will work....
you have to literally scan the first few bytes, the byte array to scan can be found as given below:-

// Get a reference to PostedFile object
HttpPostedFile myFile = filMyFile.PostedFile;

// Get size of uploaded file
int nFileLen = myFile.ContentLength;

// Allocate a buffer for reading of the file
byte[] myData = new byte[nFileLen];

// Read uploaded file from the Stream
myFile.InputStream.Read(myData, 0, nFileLen);

Open in new window


you have to scan the first few bytes of myData to see if it is a mp3 file, if not discard the same and send a failure message back to the client....
Source: http://www.codeproject.com/Articles/1757/File-Upload-with-ASP-NET
0
 
LVL 2

Expert Comment

by:Codecaesar
ID: 37792588
0
 

Author Comment

by:tia_kamakshi
ID: 37793578
Hi,

Thanks for your replies

In my application user should be able to upload pdf, doc, xls, images etc

How will below code recognise whether file is image file, excel file, pdf file, text file, rtf file etc.,

// Get a reference to PostedFile object
HttpPostedFile myFile = filMyFile.PostedFile;

// Get size of uploaded file
int nFileLen = myFile.ContentLength;

// Allocate a buffer for reading of the file
byte[] myData = new byte[nFileLen];

// Read uploaded file from the Stream
myFile.InputStream.Read(myData, 0, nFileLen);


How will this distinguish the actual file type.

line below
myFile.InputStream.Read(myData, 0, nFileLen);

will read any file in bytes.

Even the links provided is not validating file type at server side

"^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*))(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$"

but it is validating file type by its file extensions by regular expression.

This is not my requirement

Please suggest

Thanks again
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37793583
0
 

Author Comment

by:tia_kamakshi
ID: 37795027
I have gone through the articles and I realise the way you suggested is really the good way to implement.

At the same, I am finding hard to implement this in ASP.net using C#, as all above urls talks more about theory.

Please can you help me with code snippet in ASP.net using C#, that will help me more.

Regards,
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37795037
Read the first few bytes as suggested by the urls for your types:-

           
var bArray = new byte[] {10, 20, 15, 19, 17, 19};
            var mp3Array = new byte[] {10, 20, 15, 19};

            var myArray = bArray.Take(4).ToArray();

            if(myArray.SequenceEqual(mp3Array))
            {
                Console.Write("MP3 file");
            }
            else
            {
                Console.WriteLine("Not An Mp3 Array");
            }

Open in new window


I hope you are able to convert the hexadecimal to byte array to have your byte arrays for your file types....
0
 
LVL 12

Expert Comment

by:Anuradha Goli
ID: 37795544
You can use Regular expression validator

<asp:RegularExpressionValidator id=”RegularExpressionValidator1"  runat=”server”
ErrorMessage=”Only mp3 file is allowed!”  ValidationExpression =”^.+(.mp3|.MP3)$”
ControlToValidate=”FileUpload1" > </asp:RegularExpressionValidator>

Open in new window

0
 

Author Comment

by:tia_kamakshi
ID: 37797567
anuradhay
Thanks for your reply but I am not looking solution to get file type using file extensions.

BuggyCoder
Thanks for your reply. This looks fantastic.
At the same looks I am not at your level, you looks much more than me.

I am not able to convert the hexadecimal to byte array to have your byte arrays for your file types


var mp3Array = new byte[] {10, 20, 15, 19};

I am working on ASP.Net2.0, there var will not work. What should I write in place of var here

You want me to do something like this:

.ASPX Code
<input id="filMyFile" type="file" runat="server">

.CS file code
HttpPostedFile myFile = filMyFile.PostedFile;

int nFileLen = myFile.ContentLength;

byte[] bArray = new byte[nFileLen];


var mp3Array = new byte[] {10, 20, 15, 19};
var pdfArray = new byte[] {How do I get this};
var docArray = new byte[] {How do I get this};
var docxArray = new byte[] {How do I get this};
var jpegArray = new byte[] {How do I get this};
var gifArray = new byte[] {How do I get this};
var pngArray = new byte[] {How do I get this};
var xlsArray = new byte[] {How do I get this};
var xlsxArray = new byte[] {How do I get this};

var myArray = bArray.Take(4).ToArray();

if(myArray.SequenceEqual(mp3Array))
{
      Console.Write("MP3 file");
}
else if(myArray.SequenceEqual(pdfArray))
{
      Console.Write("PDF file");
}else if(myArray.SequenceEqual(docArray))
{
      Console.Write("DOC file");
}else if(myArray.SequenceEqual(docxArray))
{
      Console.Write("DOCX file");
}else if(myArray.SequenceEqual(jpegArray))
{
      Console.Write("JPEG file");
}else if(myArray.SequenceEqual(gifArray))
{
      Console.Write("GIF file");
}else if(myArray.SequenceEqual(xlsArray))
{
      Console.Write("XLS file");
}else if(myArray.SequenceEqual(xlsxArray))
{
      Console.Write("XLSX file");
}else
{
      Console.WriteLine("Unknown file type");
}


----------------------------------------------

----------------------------------------------------
application/msword
application/vnd.ms-word
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/pdf
application/excel
application/x-excel
application/x-msexcel
application/vnd.ms-excel
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application/plain
text/plain
text/html
application/powerpoint
application/mspowerpoint
application/vnd.ms-powerpoint
application/x-mspowerpoint
application/vnd.openxmlformats-officedocument.presentationml.presentation
application/rtf
application/x-rtf
text/richtext
text/rtf
image/bmp
image/x-windows-bmp
image/jpeg
image/pjpeg
image/gif
----------------------------------------------------

I need to make the filetype configurable in my configuration file as well.

Please suggest

Best Regards,
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37797759
Here is a sample for you, by far the largest sample that i have ever shared on EE:-

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

namespace EE_Console
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            //Using This code to read from file on my machine, 
            //you can replace this code with your custom
            //code to read file that is uploaded
            var pArr = File.ReadAllBytes(@"F:\Downloads\EIA100135_Receipt.pdf");
                
            //Create Instance Of Type Validator
            TypeValidator validator=new TypeValidator();

            //Lets Validate If It Is A Pdf File Or Not
            bool isValid = validator.Validate(FileType.Pdf, pArr);

            Console.Read();
        }
    }

    /// <summary>
    /// Enum to hold file types
    /// </summary>
    enum FileType
    {
        Mp3,
        Pdf
        //Create other types here...
    }

    /// <summary>
    /// Validates The File Type By Checking the File's Byte Array With Existing Signatures
    /// for each file type.
    /// </summary>
    class TypeValidator
    {
        private readonly Dictionary<FileType, byte[]> _dicTypes;

        /// <summary>
        /// Class To Hold Various File Signatures
        /// </summary>
        internal class Signatures
        {
            public const string Pdf = "25 50 44 46";
            public const string Mp3 = "49 44 33";
            //Add other type signatures here
        }

        public TypeValidator()
        {
            _dicTypes = new Dictionary<FileType, byte[]>();
            Initialize();
        }

        private void Initialize()
        {
            _dicTypes.Add(FileType.Pdf, HexToBytes(Signatures.Pdf));
            _dicTypes.Add(FileType.Mp3, HexToBytes(Signatures.Mp3));

            //Initialize other types here...
        }

        public bool Validate(FileType type, byte[] bytes)
        {
            if(!_dicTypes.ContainsKey(type)) return false;
            
            byte[] fileSig = _dicTypes[type];

            return
                bytes
                    .Take(fileSig.Length)
                    .SequenceEqual(fileSig);
        }

        private static byte[] HexToBytes(string hexNumber)
        {
            List<byte> bytes = new List<byte>();
            foreach(string str in hexNumber.Split(' '))
            {
                int number = Convert.ToInt32(str, 16);
                byte bite = Convert.ToByte(number);

                bytes.Add(bite);
            }

            return bytes.ToArray();
        }
    }
}

Open in new window


you can use this link to get signatures about other file types:-
http://www.garykessler.net/library/file_sigs.html

Happy Programming
:-)
0
 

Author Comment

by:tia_kamakshi
ID: 37800625
I really thanks for your help you did.

public bool Validate(FileType type, byte[] bytes)
    {
        if (!_dicTypes.ContainsKey(type)) return false;

        byte[] fileSig = _dicTypes[type];

        return
            bytes            
                .Take(fileSig.Length)
                .SequenceEqual(fileSig);
    }


In Asp.net 2.0 it is giving error on line
.Take(fileSig.Length)

Error saying

Error      1      'System.Array' does not contain a definition for 'Take'      D:\Workspace\RandD\XMLXslt\Website\App_Code\TypeValidator.cs


Please can you help me in fixing this return type

return
            bytes            
                .Take(fileSig.Length)
                .SequenceEqual(fileSig);
               
How do we do this in ASP.net 2.0 using C#

I have never worked on above versions of ASP.net 2.0 and this type of return does not help in ASP.net2.0

and actually what these 2 lines are doing.

It would be great if you help me in understanding this as well

Best regards for your great help
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37802694
public bool Validate(FileType type, byte[] bytes)
        {
            if(!_dicTypes.ContainsKey(type)) return false;
           
            byte[] fileSig = _dicTypes[type];
            byte[] newArr = new byte[fileSig.Length];

            Array.Copy(bytes, newArr, newArr.Length);
            return newArr.SequenceEqual(fileSig);
        }
0
 

Author Comment

by:tia_kamakshi
ID: 37802747
Thanks for this.

Now I am getting the error below

Error      1      'System.Array' does not contain a definition for 'SequenceEqual'      

Please help me in fixing this

Regards,
0
 
LVL 20

Accepted Solution

by:
BuggyCoder earned 500 total points
ID: 37804729
public bool Validate(FileType type, byte[] bytes)
        {
            try
            {
                if (!_dicTypes.ContainsKey(type)) return false;

                byte[] fileSig = _dicTypes[type];
                byte[] newArr = new byte[fileSig.Length];

                Array.Copy(bytes, newArr, newArr.Length);
                bool retVal = true;

                for (int i = 0; i < newArr.Length; i++)
                {
                    if (fileSig[i] != newArr[i])
                    {
                        retVal = false;
                        break;
                    }
                }

                return retVal;
            }
            catch (Exception)
            {
                throw;
            }
        }

Open in new window

0
 

Author Closing Comment

by:tia_kamakshi
ID: 37815830
Big Big Thanks to you for your great help
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

In .NET 2.0, Microsoft introduced the Web Site.  This was the default way to create a web Project in Visual Studio 2005.  In Visual Studio 2008, the Web Application has been restored as the default web Project in Visual Studio/.NET 3.x The Web Si…
We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now