Skip to main content
All docs
V24.1

Validate Uploaded Files

  • 3 minutes to read

To prevent a threat actor from uploading/executing files with malicious code (CWE-434), you should validate uploaded files and always specify accepted/valid file types.

Validate File Extensions

By default, DevExpress ASP.NET Web Forms controls allow users to upload the following file types (file extensions):

Control

Allowed File Extensions

Binary Image

jpeg, jpg, gif, png

File Manager

any

Html Editor

Rich Text Editor

doc, docx, epub, html, htm, mht, mhtml, odt, txt, rtf, xml

Spreadsheet

xlsx, xlsm, xls, xltx, xltm, xlt, txt, csv

Upload Control

any

If you do not restrict acceptable/valid file extensions for the DevExpress File Manager and Upload Control, a threat actor may be able to upload a malicious ASPX file to your server. Once the threat actor navigates to this ASPX page, your application will execute the malicious code as if it was a part of your application.

Use the AllowedFileExtensions property to set acceptable/valid file extensions. Validation will fail and the control will display an error message if a file extension has not been specified. The NotAllowedFileExtensionErrorText property allows you to customize error text.

The following code snippet limits file upload operations (when using the DevExpress File Manager control) to JPG and PNG files:

<dx:ASPxFileManager ID="FileManager" runat="server">
    <Settings AllowedFileExtensions=".jpg, .png" />
</dx:ASPxFileManager>

Validate File Content

You should always validate uploaded files before saving files to a server. If you do not validate uploaded files, a threat actor can upload a file with a malicious script by simply using a valid file extension (CWE-79).

The ASPxBinaryImage control automatically checks whether an uploaded file is an image. In the following example, the DevExpress Upload Control checks whether the uploaded file is a valid image:

<dx:ASPxUploadControl runat="server" ID="UploadControl" ShowUploadButton="True" 
    OnFileUploadComplete="FileUploadComplete">
    <ValidationSettings AllowedFileExtensions=".jpg" MaxFileSize="1000000" />
</dx:ASPxUploadControl>
protected void FileUploadComplete(object sender, DevExpress.Web.FileUploadCompleteEventArgs e) {
    if(!e.UploadedFile.IsValid) return;

    using(var stream = e.UploadedFile.FileContent) {
        if (!IsValidImage(stream)) {
            e.ErrorText = "Invalid image.";
            e.IsValid = false;
        }
        else {
            string fileName = Server.MapPath("~/App_Data/UploadFiles/avatar.jpg");
            e.UploadedFile.SaveAs(fileName, true);
        }
    }
}

static bool IsValidImage(Stream stream) {
    try {
        using(var image = System.Drawing.Image.FromStream(stream)) {
            return true;
        }
    }
    catch(Exception) {
        return false;
    }
}

Use third-party antivirus tools to validate uploaded files where possible.

Disable Uploaded File Execution

To protect your application, restrict the execution of files located in the upload folder. The following code snippets restricts file execution for the UploadedFiles/Images folder:

<location path="UploadedFiles/Images">
    <system.webServer>
        <handlers>
            <clear />
            <add name="StaticFile"
                 path="*"
                 verb="*"
                 modules="StaticFileModule"
                 resourceType="Either"
                 requireAccess="Read" />
      </handlers>
    </system.webServer>
</location>

Validate Response Content Type

Web browsers use MIME-type sniffing techniques to identify file type based on file content. Threat actors can exploit this technique and create malicious files that have valid extensions, but browsers interpret these files as executable. Follow the steps below to prevent browsers from content sniffing:

  1. Specify exact content type when adding binary data to the response.
  2. Add the X-CONTENT-TYPE-OPTIONS="nosniff" header to the response.

    Response.ContentType = "image/jpeg";
    Response.Headers.Add("X-Content-Type-Options", "nosniff");
    
See Also