views:

230

answers:

4

I am using FileUpload control to facilitate Image file upload on my website. I want to restrict a user to upload only Image file. I am using

 if (fupFirmLogo.PostedFile.ContentType == "image/Jpeg")
            { 

            } 

to check if the file is a image or not. I want to allow all image extensions like PNG, GiF, Jpeg, tif , BMP etc. How should I do it.

A: 

you should use regular expression to validate that is an image or not, might be the better option

some thing like:

 public static bool IsValidImage(this string fileName)
    {           
        Regex regex = new Regex(@"(.*?)\.(jpg|JPG|jpeg|JPEG|png|PNG|gif|GIF|bmp|BMP)$");
        return regex.IsMatch(fileName);
    }

Then you check:

if (fupFirmLogo.FileName.IsValidImage())
{
    //Do your code
}
else
 {
    //Not a valid image
  }
anishmarokey
Can't a user can delibrately change the extension of the file i.e from .exe to .jpeg. I think, this method will allow it.
vaibhav
i think no. How can you change the an .exe to a .jpg ?
anishmarokey
Agreed that this might have a vulnerability. I like the regex idea though. Would including regex on fupFirmLogo.PostedFile.ContentType to check for "^image/.+$" iron out any vulnerability?
Eddie
@anishmarokey - Right click, change .exe to .jpg. The file contents are the same, it just appears to be an image now. You aren't really converting an exe to a jpg.
Tommy
+1  A: 

You could define an array of known image types:

public static readonly string[] _imageMimeTypes = new[] { "image/jpeg", "image/png" };

and then test whether the posted content type is in this array:

if (_imageMimeTypes.Contains(fupFirmLogo.PostedFile.ContentType))
{
    // ...
}
Darin Dimitrov
Darin, I think combining your idea with anishMarokey's is the best way to go. Check the MIME types, but do so from a common class so that it is reusable. This is the method that we use on our file upload controls.
Tommy
A: 

I hope this will help you out. Try below code.

    Image uploadedImage = null;  
    if (ImageUpload.HasFile && ImageUpload.FileName != string.Empty && ImageUpload.FileContent.Length > 0)  
    {  
        try  
        {  
            uploadedImage = Image.FromStream(ImageUpload.PostedFile.InputStream);  
        }  
        catch (Exception ex)  
        {  
            lblUploadStatus.Text = "Selected file is not an image.<br />" + ex.Message;  
       }  

       if (uploadedImage != null)  
       {  
           string savePath = string.Format("{0}/{1}", Server.MapPath("~/images/orig/upload_temp"), ImageUpload.FileName);  
           uploadedImage.Save(savePath, ImageFormat.Jpeg);  
       }  
   }  
GS_Guy
A: 

The only problem with the solutions above is that the file will have to be uploaded to the server before you can check their file types.

If you put some Javascript in the onSubmit call, you can read the filename and test there, returning false if its not a valid file name.

This will be much more friendly on your bandwidth.

<form method="post" enctype="multipart/form-data" onsubmit="return submit(this)">
  <input id="inputControl" name="file" type="file" />
</form>

Then

function submit(form) {
  var fileName = $('#inputControl').val().replace(/.*(\/|\\)/, '');
  // check the filename here, return false if its not an image.
}
Russ C
@Russ - you still have the I renamed a .exe to .jpg issue here. This will probably catch 99% of things out there, but you still need server side validation. Also, what about those that turn off JS?
Tommy
Then it'll still post the file - the main thing is though the majority of cases this will reduce the bandwidth overheads. I'd still to the Image.FromStream solution above but starting this way can cut out a lot of potential problems for little effort.
Russ C