I programmed a FileUpload which is already working fine. Now I'd like to add a feature: At the form where I browse for the file I want to upload, I'd like to validate the file type.
I'd like to allow only image files in the formats .jpg, .gif and .png and show an error message if the file is not valid (= if the format is not allowed)
Does anybody know how i can program this feature?
Please mark as answered if I helped.
I don't answer personal emails unless I know you or of you. Feel free to post in the forum to get an answer from me.
Client-Side Validation of File Types Permissible to Upload
There are several methods you can use to control the types of files that are uploaded to the server. Unfortunately, there is no bullet-proof method to protect you from someone uploading files that would be considered malicious. You can take a few steps,
however, to make this process of allowing end users to upload files a little more manageable.
One nice method you can employ is to use the ASP.NET validation controls that are provided for free with ASP.NET. These controls enable you to do a regular-expression check upon the file that is being uploaded to see if the extension of the file is one you
permit to be uploaded.
This is ideal for browsers that allow client-side use of the validation controls because it forces the checking to be done on the client; the file is not uploaded to the server if the signature isn't one you allow. Listing 3 shows you an example of using
validation controls to accomplish this task.
Note The use of validation controls is not explained here. Take a look at
Validating ASP.NET Server Controls for a complete explanation of validation controls and how to use them in your ASP.NET pages.
Listing 3. Using validation controls to restrict the types of files uploaded to the server
This simple ASP.NET page uses validation controls so that the end user can only upload .mp3, .mpeg, or .m3u files to the server. If the file type is not one these three choices, a
Validation control throws an exception onto the screen. This is shown in Figure 4.
Figure 4. Validating the file type using validation controls
Using Validation controls is not a foolproof way of controlling the files that are uploaded to the server. It wouldn't be too hard for someone to change the file extension of a file so it would be accepted and uploaded to the server, thereby bypassing
this simple security model.
Adding Server-Side File Type Validation
You just saw an easy way to add some ASP.NET validation server controls to your ASP.NET page to perform a client side validation of the file extension (in just a textual manner). Now let's take a look at how to perform a similar operation on the server-side.
This is presented in Listing 4.
Listing 4. Checking the file type on the server
Visual Basic
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs)
If FileUpload1.HasFile Then
Dim fileExt As String
fileExt = System.IO.Path.GetExtension(FileUpload1.FileName)
If (fileExt = ".mp3") Then
Try
FileUpload1.SaveAs("C:\Uploads\" & _
FileUpload1.FileName)
Label1.Text = "File name: " & _
FileUpload1.PostedFile.FileName & "<br>" & _
"File Size: " & _
FileUpload1.PostedFile.ContentLength & " kb<br>" & _
"Content type: " & _
FileUpload1.PostedFile.ContentType
Catch ex As Exception
Label1.Text = "ERROR: " & ex.Message.ToString()
End Try
Else
Label1.Text = "Only .mp3 files allowed!"
End If
Else
Label1.Text = "You have not specified a file."
End If
End Sub
Now, by using the GetExtension method from the System.IO.Path namespace, you can perform basically the same operation. It is important to note that this doesn't get around an end user's ability to simply change the file extension to something
that works and upload that altered file to the hosting server.
one way you can check is by peeking at the filestream in the posted file.
you can open a reader and take the first 10 or so bytes. And from the header info you can usually tell what type of file it is.
Its not bulletproof however, because the location of the filetype info is not always in the same place or format.
heres an if i used to check for valid image types a while ago. i just passed it the first chunk in my upload
//checks if it is an image
private bool IsImage(byte[] data)
{
//read 64 bytes of the stream only to determine the type
string myStr = System.Text.Encoding.ASCII.GetString(data).Substring(0,16);
//check if its definately an image.
if(myStr.Substring(8,2).ToString().ToLower()!="if")
{
//its not a jpeg
if(myStr.Substring(0,3).ToString().ToLower() != "gif")
{
//its not a gif
if(myStr.Substring(0,2).ToString().ToLower() != "bm")
{
//its not a .bmp
if(myStr.Substring(0,2).ToString().ToLower() != "ii")
{
//its not a tiff
//ProcessErrors("notImage");
this.myFile.PostedFile.InputStream.Close();
myStr = null;
return false;
}
}
}
}
myStr = null;
return true;
}
hth
mcm
Marked as answer by jessjing on Dec 07, 2006 04:38 AM
while this solution is still workable the problem still exists where a user can easily change the extension of the filename to bypass this check. the only "sure fire" way to know if its an image is to peek at the file stream as i demonstrated above.
Well, I know that I can't check if it's an image of not at client side , but not all users think to change file extension , but we can use that solution as indicator to the user that we accept images only, and at server side we can use your "sure fire"
way to detect images inly, anyway Great Topic , thank you very much.
mcmcomasp
while this solution is still workable the problem still exists where a user can easily change the extension of the filename to bypass this check. the only "sure fire" way to know if its an image is to peek at the file stream as i demonstrated above.
That's pretty funny the FileUpload control's contentType can lie to you. I guess it just loads the file into a byte[] and let's you take it from there.
I think you can test the real file contents information by loading the file into a System.Drawing.Image and testing it's RawFormat property. There, you will find a Guid that is unique for each image type. If you can't load the file into an Image, I guess it's
not a jpg, png or gif as you requested.
KingDario
Member
97 Points
61 Posts
Fileupload: allow only .jpg .gif and .png
Dec 06, 2006 01:10 PM|LINK
Hi all
I programmed a FileUpload which is already working fine. Now I'd like to add a feature: At the form where I browse for the file I want to upload, I'd like to validate the file type.
I'd like to allow only image files in the formats .jpg, .gif and .png and show an error message if the file is not valid (= if the format is not allowed)
Does anybody know how i can program this feature?
haoest
Participant
1768 Points
404 Posts
Re: Fileupload: allow only .jpg .gif and .png
Dec 06, 2006 01:39 PM|LINK
i can always rename my a.exe to a.jpg, can i not?
but i guess you could try/catch opening the uploaded stream as a .NET image, and reject the file if exception is caught.
jose_jimenez
Contributor
2504 Points
484 Posts
Re: Fileupload: allow only .jpg .gif and .png
Dec 06, 2006 04:31 PM|LINK
how about using a regular expression validator?
I don't answer personal emails unless I know you or of you. Feel free to post in the forum to get an answer from me.
jessjing
Contributor
4392 Points
872 Posts
Re: Fileupload: allow only .jpg .gif and .png
Dec 07, 2006 02:10 AM|LINK
hi,
look at this
Client-Side Validation of File Types Permissible to Upload
There are several methods you can use to control the types of files that are uploaded to the server. Unfortunately, there is no bullet-proof method to protect you from someone uploading files that would be considered malicious. You can take a few steps, however, to make this process of allowing end users to upload files a little more manageable.
One nice method you can employ is to use the ASP.NET validation controls that are provided for free with ASP.NET. These controls enable you to do a regular-expression check upon the file that is being uploaded to see if the extension of the file is one you permit to be uploaded.
This is ideal for browsers that allow client-side use of the validation controls because it forces the checking to be done on the client; the file is not uploaded to the server if the signature isn't one you allow. Listing 3 shows you an example of using validation controls to accomplish this task.
Listing 3. Using validation controls to restrict the types of files uploaded to the server
<asp:FileUpload ID="FileUpload1" runat="server" /><br /> <br /> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" /> <br /> <br /> <asp:Label ID="Label1" runat="server"></asp:Label> <asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server" ErrorMessage="Only mp3, m3u or mpeg files are allowed!" ValidationExpression="^(([a-zA-Z]:)|(\\{2}\w+)\$?)(\\(\w[\w].*)) +(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" ControlToValidate="FileUpload1"></asp:RegularExpressionValidator> <br /> <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server" ErrorMessage="This is a required field!" ControlToValidate="FileUpload1"></asp:RequiredFieldValidator>This simple ASP.NET page uses validation controls so that the end user can only upload .mp3, .mpeg, or .m3u files to the server. If the file type is not one these three choices, a Validation control throws an exception onto the screen. This is shown in Figure 4.
Figure 4. Validating the file type using validation controls
Using Validation controls is not a foolproof way of controlling the files that are uploaded to the server. It wouldn't be too hard for someone to change the file extension of a file so it would be accepted and uploaded to the server, thereby bypassing this simple security model.
Adding Server-Side File Type Validation
You just saw an easy way to add some ASP.NET validation server controls to your ASP.NET page to perform a client side validation of the file extension (in just a textual manner). Now let's take a look at how to perform a similar operation on the server-side. This is presented in Listing 4.
Listing 4. Checking the file type on the server
Visual Basic
Protected Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) If FileUpload1.HasFile Then Dim fileExt As String fileExt = System.IO.Path.GetExtension(FileUpload1.FileName) If (fileExt = ".mp3") Then Try FileUpload1.SaveAs("C:\Uploads\" & _ FileUpload1.FileName) Label1.Text = "File name: " & _ FileUpload1.PostedFile.FileName & "<br>" & _ "File Size: " & _ FileUpload1.PostedFile.ContentLength & " kb<br>" & _ "Content type: " & _ FileUpload1.PostedFile.ContentType Catch ex As Exception Label1.Text = "ERROR: " & ex.Message.ToString() End Try Else Label1.Text = "Only .mp3 files allowed!" End If Else Label1.Text = "You have not specified a file." End If End SubC#
protected void Button1_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { string fileExt = System.IO.Path.GetExtension(FileUpload1.FileName); if (fileExt == ".mp3") { try { FileUpload1.SaveAs("C:\\Uploads\\" + FileUpload1.FileName); Label1.Text = "File name: " + FileUpload1.PostedFile.FileName + "<br>" + FileUpload1.PostedFile.ContentLength + " kb<br>" + "Content type: " + FileUpload1.PostedFile.ContentType; } catch (Exception ex) { Label1.Text = "ERROR: " + ex.Message.ToString(); } } else { Label1.Text = "Only .mp3 files allowed!"; } } else { Label1.Text = "You have not specified a file."; } }Now, by using the GetExtension method from the System.IO.Path namespace, you can perform basically the same operation. It is important to note that this doesn't get around an end user's ability to simply change the file extension to something that works and upload that altered file to the hosting server.
mcmcomasp
Contributor
6834 Points
1436 Posts
Re: Fileupload: allow only .jpg .gif and .png
Dec 07, 2006 02:24 AM|LINK
one way you can check is by peeking at the filestream in the posted file.
you can open a reader and take the first 10 or so bytes. And from the header info you can usually tell what type of file it is.
Its not bulletproof however, because the location of the filetype info is not always in the same place or format.
heres an if i used to check for valid image types a while ago. i just passed it the first chunk in my upload
//checks if it is an image private bool IsImage(byte[] data) { //read 64 bytes of the stream only to determine the type string myStr = System.Text.Encoding.ASCII.GetString(data).Substring(0,16); //check if its definately an image. if(myStr.Substring(8,2).ToString().ToLower()!="if") { //its not a jpeg if(myStr.Substring(0,3).ToString().ToLower() != "gif") { //its not a gif if(myStr.Substring(0,2).ToString().ToLower() != "bm") { //its not a .bmp if(myStr.Substring(0,2).ToString().ToLower() != "ii") { //its not a tiff //ProcessErrors("notImage"); this.myFile.PostedFile.InputStream.Close(); myStr = null; return false; } } } } myStr = null; return true; }hthmcm
haoest
Participant
1768 Points
404 Posts
Re: Fileupload: allow only .jpg .gif and .png
Dec 07, 2006 03:52 AM|LINK
I like mcmcomasp's solution slightly better.
You realize that you are doing all that work and I can just rename my file? Spend your time on other features of your project, I'd suggest.
moud_gersy
Member
16 Points
12 Posts
Re: Fileupload: allow only .jpg .gif and .png
Feb 10, 2008 07:53 PM|LINK
WoW, Egypt Winnnnnnnn,[:D][:D]
and I just found the solution for that problem
try this if you want
___________________________
<script language="javascript"> function ValidateFile(source, args) { try { var fileAndPath= document.getElementById(source.controltovalidate).value; var lastPathDelimiter=fileAndPath.lastIndexOf("\\"); var fileNameOnly=fileAndPath.substring(lastPathDelimiter+1); var file_extDelimiter=fileNameOnly.lastIndexOf("."); var file_ext=fileNameOnly.substring(file_extDelimiter+1).toLowerCase(); if(file_ext!="jpg") { args.IsValid = false; if(file_ext!="gif") args.IsValid = false; if(file_ext!="png") { args.IsValid = false; return; } } }catch(err) { txt="There was an error on this page.\n\n"; txt+="Error description: " + err.description + "\n\n"; txt+="Click OK to continue.\n\n"; txt+=document.getElementById(source.controltovalidate).value; alert(txt); } args.IsValid = true; } </script> <asp:FileUpload ID="FileUpload1" runat="server" /> <asp:CustomValidator ID="CustomValidator1" ClientValidationFunction="ValidateFile" runat="server" ControlToValidate="FileUpload1" Display="dynamic" ErrorMessage="images only "> </asp:CustomValidator>____________________________
please post comments if there any comment,I'm not sure about it yet,
Thank you
mcmcomasp
Contributor
6834 Points
1436 Posts
Re: Fileupload: allow only .jpg .gif and .png
Feb 12, 2008 02:19 PM|LINK
while this solution is still workable the problem still exists where a user can easily change the extension of the filename to bypass this check. the only "sure fire" way to know if its an image is to peek at the file stream as i demonstrated above.
hth,
mcm
moud_gersy
Member
16 Points
12 Posts
Re: Fileupload: allow only .jpg .gif and .png
Feb 13, 2008 07:37 PM|LINK
Well, I know that I can't check if it's an image of not at client side , but not all users think to change file extension , but we can use that solution as indicator to the user that we accept images only, and at server side we can use your "sure fire" way to detect images inly, anyway Great Topic , thank you very much.
Zeerover
Member
7 Points
13 Posts
Re: Fileupload: allow only .jpg .gif and .png
Jul 09, 2008 11:02 AM|LINK
That's pretty funny the FileUpload control's contentType can lie to you. I guess it just loads the file into a byte[] and let's you take it from there.
I think you can test the real file contents information by loading the file into a System.Drawing.Image and testing it's RawFormat property. There, you will find a Guid that is unique for each image type. If you can't load the file into an Image, I guess it's not a jpg, png or gif as you requested.
System.Drawing.Image img = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream);
if (img.RawFormat.Guid == System.Drawing.Imaging.ImageFormat.Jpeg.Guid) {do something}
Or, if you want to return the type of the image, try this:
public static string MimeType(System.Drawing.Image imgPhoto)
{
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageDecoders())
{
if (codec.FormatID == imgPhoto.RawFormat.Guid)
return codec.MimeType;
}
return "image/unknown";
}