Insecure file upload - DLL Injection - C-Sharp

Insecure file upload - DLL Injection - C-Sharp

Need

Secure file upload and validation process

Context

  • Usage of C# 7.0 for modern language features and enhancements
  • Usage of Microsoft.AspNetCore.Mvc for building web applications using the MVC pattern
  • Usage of Microsoft.AspNetCore.Http for handling HTTP requests and responses in .NET Core applications

Description

Non compliant code

        public class FileUploadController : Controller
{
    [HttpPost("UploadFile")]
    public async Task UploadFile(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return Content("file not selected");

        var path = Path.Combine(
                    Directory.GetCurrentDirectory(), "wwwroot",
                    file.GetFilename());

        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }

        return RedirectToAction("Files");
    }
}
        
        

In the above code, we have a controller named FileUploadController which is responsible for handling file uploads. It has a method UploadFile which accepts a file from the user and saves it to a specified directory.

The vulnerability lies in the fact that there is no validation or checks performed on the type of file being uploaded. This means that a user can upload a malicious DLL file, which can then be executed on the server, leading to a DLL Injection attack.

When the UploadFile method is called, it first checks if a file has been provided. If not, it returns a message saying "file not selected". If a file is provided, it creates a path to the directory where the file will be saved. It then creates a new FileStream object and copies the contents of the uploaded file into it.

At no point during this process is there any validation to ensure that the file being uploaded is safe. There are no checks to see if the file is a DLL file, and there are no checks to see if the DLL file contains any malicious code. This leaves the application open to DLL Injection attacks.

Steps

  • Implement file extension validation to ensure only allowed file types are uploaded
  • Use a secure file storage location instead of the 'wwwroot' directory
  • Implement file content validation to ensure the uploaded file is not a malicious DLL
  • Consider implementing a file size limit to prevent large files from being uploaded
  • Implement proper error handling and logging for file upload failures

Compliant code

        public class FileUploadController : Controller
{
    private readonly string[] permittedExtensions = { ".txt", ".png" }; // Add your permitted file extensions here
    private readonly long maxFileSize = 1024 * 1024 * 10; // 10MB, change this to your needs

    [HttpPost("UploadFile")]
    public async Task UploadFile(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return Content("file not selected");

        var ext = Path.GetExtension(file.FileName).ToLowerInvariant();

        if (string.IsNullOrEmpty(ext) || !permittedExtensions.Contains(ext))
            return Content("invalid file extension");

        if(file.Length > maxFileSize)
            return Content("file size exceeded limit");

        var path = Path.Combine(
                    Directory.GetCurrentDirectory(), "secure_folder", // Change 'secure_folder' to your secure directory
                    file.FileName);

        try
        {
            using (var stream = new FileStream(path, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }
        }
        catch(Exception ex)
        {
            // Log the exception
            return Content("file upload failed");
        }

        return RedirectToAction("Files");
    }
}
        
        

The updated code now includes several security measures to prevent insecure file uploads and DLL Injection:

1. File Extension Validation: The code checks the file extension against a list of permitted extensions before the file is saved. This prevents the upload of potentially harmful file types, such as DLL files.

2. File Size Limit: The code checks the size of the file and rejects the upload if the file size exceeds a specified limit. This can prevent Denial of Service (DoS) attacks that attempt to overwhelm the server with large files.

3. Secure File Storage Location: The file is saved to a secure directory instead of the 'wwwroot' directory. This can prevent unauthorized access to the uploaded files.

4. Error Handling and Logging: The code includes a try-catch block to handle any exceptions that occur during the file upload process. This can help to identify and fix any issues that occur during file upload.

References