ClamAV Antivirus Scan On File Upload Content In .NET Application

Introduction

 
Most ASP.NET Web applications have  file upload functionality where users can upload files and those files are saved on a server or blob storage. But without performing anti-virus scanning or other content checking against the uploaded file, attackers could target other users of the application by uploading malware to the server.

The application should perform filtering and content checking on any files which are uploaded to the server. Files should be thoroughly scanned and validated against an antivirus scanner with up-to-date virus signatures before being made available to other users. Any files flagged as malicious should be discarded or deleted immediately.
 
To achieve this, we will use open source antivirus engine called ClamAV via nClam NuGet package, a pure .NET client to ClamAV.
 
This article demonstrates how we can perform secure and effective file scanning using ClamAV antivirus.
 
Prerequisites
  • ClamAV server should be up and running on specific port. In case, you want to run ClamAV server in localhost, you can follow subsequent steps below.

Running ClamAV on localhost using Docker Image

 
This step is optional if you already have the ClamAV server. Here I used docker image as simplest and easiest way to run it.
 
ClamAV demon is a Dockerized open source antivirus image. Let’s follow below simple steps to install and running on localhost via default TCP port 3310. I am assuming you have Docker desktop latest version installed and running on your PC.
 
Execute below commands from command prompt.
  • docker run -d -p 3310:3310 mkodockx/docker-clamav:alpine
  • docker run -d -p 3310:3310 mk0x/docker-clamav
  • docker ps
ClamAV Antivirus Scan On File Upload Content In .NET Application
 
The ClamAV Server is now set up!
 
For more details, you can check here.
 

Implementing ClamAV Antivirus scan on uploaded files in .NET application

 
Now we are ready to run on-demand scans and anything from code using nClam. To demonstrate an example, here I created a simple file upload UI in ASP.NET Core MVC Web application (you can have similar ASP.NET website in WebForms or MVC with file upload input) where we will browse and upload different types of file like PDF, IMAGE, ZIP, DCOX etc.
 
The Approach
  1. Install nClam NuGet package.
  2. Add ClamAV server and port to config file.
  3. Read file from File upload and convert to byte array.
  4. Scan file byte array against ClamClient and validate ClamScanResult object.
  5. Test ClamAV scan against a valid file
  6. Test ClamAV scan against an Anti Malware test file
Step 1 - Install nClam NuGet package
 
Install below NuGet package from NuGet package manager into your project.
  1. <PackageReference Include="nClam" Version="4.0.1" />  
Step 2 - Add ClamAV server and port to appsettings.json
  1. "ClamAVServer": {  
  2.   "URL": "localhost",  
  3.   "Port": "3310"  
  4. }  
Step 3
 
Read file from File upload and convert to byte array
 
Step 4 - Scan file byte array against ClamClient and validate ClamScanResult object
 
ClamClient scan result returns with ClamScanResult enum values which tell you if your scan was clean or a virus was detected. Here is some sample code:
  1. private readonly ILogger<HomeController> _logger;  
  2. private readonly IConfiguration _configuration;  
  3. public HomeController(ILogger<HomeController> logger,IConfiguration configuration)  
  4. {  
  5.     _logger = logger;  
  6.     _configuration = configuration;  
  7. }  
  8.   
  9. [HttpPost]  
  10. public async Task<IActionResult> UploadFile(IFormFile file)  
  11. {  
  12.     if (file == null || file.Length == 0)  
  13.         return Content("file not selected");  
  14.   
  15.     var ms = new MemoryStream();  
  16.     file.OpenReadStream().CopyTo(ms);  
  17.     byte[] fileBytes = ms.ToArray();  
  18.     
  19.     try  
  20.     {  
  21.         this._logger.LogInformation("ClamAV scan begin for file {0}", file.FileName);  
  22.         var clam = new ClamClient(this._configuration["ClamAVServer:URL"],   
  23.                                   Convert.ToInt32(this._configuration["ClamAVServer:Port"]));  
  24.         var scanResult = await clam.SendAndScanFileAsync(fileBytes);    
  25.         switch (scanResult.Result)  
  26.         {  
  27.             case ClamScanResults.Clean:  
  28.                 this._logger.LogInformation("The file is clean! ScanResult:{1}", scanResult.RawResult);  
  29.                 break;  
  30.             case ClamScanResults.VirusDetected:  
  31.                 this._logger.LogError("Virus Found! Virus name: {1}", scanResult.InfectedFiles.FirstOrDefault().VirusName);  
  32.                 break;  
  33.             case ClamScanResults.Error:  
  34.                 this._logger.LogError("An error occured while scaning the file! ScanResult: {1}", scanResult.RawResult);  
  35.                 break;  
  36.             case ClamScanResults.Unknown:  
  37.                this._logger.LogError("Unknown scan result while scaning the file! ScanResult: {0}", scanResult.RawResult);  
  38.                 break;  
  39.         }  
  40.     }  
  41.     catch (Exception ex)  
  42.     {  
  43.   
  44.         this._logger.LogError("ClamAV Scan Exception: {0}", ex.ToString());  
  45.     }  
  46.     this._logger.LogInformation("ClamAV scan completed for file {0}", file.FileName);  
  47.   
  48.     return RedirectToAction("Index");  
  49. }  
In case you have file content in base 64 strings, then convert it to byte array and send the same byte array to ClamClient for scanning.
 
Step 5 - Test ClamAV scan against a valid file
 
Now we are ready to test our code against a valid PDF and images.
 
ClamAV Antivirus Scan On File Upload Content In .NET Application
 
ClamAV Antivirus Scan On File Upload Content In .NET Application
 
Step 6 - Test ClamAV scan against an Anti Malware test file
 
As a POC, the EICAR file was uploaded. This is a sample file used to test the response of anti-virus software. You can download a sample file from https://www.eicar.org/?page_id=3950. You may need to pause you antivirus protection on your  device to perform this activity.
 
ClamAV Antivirus Scan On File Upload Content In .NET Application
 
ClamAV Antivirus Scan On File Upload Content In .NET Application
 
Below information is  from application console log,
 
ClamAV Antivirus Scan On File Upload Content In .NET Application
 

Conclusion

 
In this article, we have seen how to run ClamAV in localhost using docker image and implemented and tested antivirus scan with a valid file and a virus infected file. The application identified the upload of this file with scan result, now you can add your logic to remove the file. Hope you found this information useful! Sharing is caring!