Helper to validate image in MVC

In almost 90% of projects, we need to upload images to server and store them. In most cases, hackers try to exploit an image upload system and try to upload exploitable materials like web-shells, some harmful scripts, table deletions scripts, etc.

In almost 90% of projects, we need to upload images to server and store them. In most cases, hackers try to exploit an image upload system and try to upload exploitable materials like web-shells, some harmful scripts, table deletions scripts, etc. To prevent this, I have written one helper function which validates file in many conditions and makes sure the file is in correct image format. The code is not fully written by me, I researched many articles and filtered the conditions which helps us to validate the required output.
/// <summary>
/// Verifies that a uploading file is in valid Image format
/// </summary>
/// <param name="postedFile">File which is selected for upload</param>
/// <param name="imageMinBytes">Minimum file size in byte</param>
/// <param name="imageMaxBytes">Maximum file size in byte</param>
/// <returns>true if the file is a valid image format and false if it's not</returns>
public static bool IsValidImageFormat(HttpPostedFileBase postedFile, int imageMinBytes, long imageMaxBytes)
{
    //-------------------------------------------
    //  Check the image extension
    //-------------------------------------------
    if (Path.GetExtension(postedFile.FileName).ToLower() != ".jpg"
        && Path.GetExtension(postedFile.FileName).ToLower() != ".png"
        && Path.GetExtension(postedFile.FileName).ToLower() != ".gif"
        && Path.GetExtension(postedFile.FileName).ToLower() != ".jpeg")
    {
        return false;
    }

    //-------------------------------------------
    //  Check the image MIME types
    //-------------------------------------------
    if (postedFile.ContentType.ToLower() != "image/jpg" &&
                postedFile.ContentType.ToLower() != "image/jpeg" &&
                postedFile.ContentType.ToLower() != "image/pjpeg" &&
                postedFile.ContentType.ToLower() != "image/gif" &&
                postedFile.ContentType.ToLower() != "image/x-png" &&
                postedFile.ContentType.ToLower() != "image/png")
    {
        return false;
    }

    //-------------------------------------------
    //  Attempt to read the file and check the first bytes
    //-------------------------------------------
    try
    {
        if (!postedFile.InputStream.CanRead)
        {
            return false;
        }

        if (postedFile.ContentLength < imageMinBytes)
        {
            return false;
        }

        byte[] buffer = new byte[512];
        postedFile.InputStream.Read(buffer, 0, 512);
        string content = System.Text.Encoding.UTF8.GetString(buffer);
        if (Regex.IsMatch(content, @"<script|<html|<head|<title|<body|
        <pre|<table|<a\s+href|<img|<plaintext|<cross\-domain\-policy",
            RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline))
        {
            return false;
        }
    }
    catch (Exception)
    {
        return false;
    }

    //-------------------------------------------
    //  Try to instantiate new Bitmap, if .NET will throw exception
    //  we can assume that it's not a valid image
    //-------------------------------------------

    try
    {
        using (var bitmap = new System.Drawing.Bitmap(postedFile.InputStream))
        {
        }
    }
    catch (Exception)
    {
        return false;
    }

    return true;
}
Hope it will help you. Let me know your thoughts!  

If you find anything inappropriate please report it here.

Leave a Reply

Please login to post comments.

Top