This article will demonstrate about the what is the easiest way to protect our files/documents from viruses before they got uploaded to a storage location. Usually, without performing anti-virus scanning or other content checking against the uploaded file, there might be a chance that attackers could target other users of the application by uploading malware to the server.
In today's article, we will perform filtering and content checking on any files which are uploaded to the server. Files should be thoroughly scanned and validated against an anti-virus 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.
Prerequisites
I've been using the .Net 5.0 template to perform this operation and here I'm sharing the link to install the SDK,
Create a Web API project with a .Net 5.0 Template.
Step 2
Install the Package which will be used for the virus when uploading any document to the API endpoint.
For more details about nclam & Clam Av, you can check
here.
Step 3
There are two possible ways in which we can use this Clam AV Server in our project,
- Running the Clam Av Server under the Docker image
- Using their own Clam Av Ip address to scan our files (If clam server is already installed in our machine)
Running the Clam Av Server under the Docker image
Setup the Clam server - in local using Docker
- Click here to install the docker.
- Use the below commands in command prompt to setup the clam Av server locally
- docker run -d -p 3310:3310 mkodockx/docker-clamav:alpine
- docker run -d -p 3310:3310 mk0x/docker-clamav
- docker ps
Once this setup is done, let's create an endpoint and the necessary configuration to scan our files under that clam Av server by docker image. Add the Clam Av port configuration in the appsettings.json file.
appsettings.json
- {
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "AllowedHosts": "*",
- "ClamAVServer": {
- "URL": "localhost",
- "Port": "3310"
- }
- }
Create an endpoint and read the file from the file upload endpoint and convert the file to a byte array. ClamClient scan result returns with ClamScanResult enum values which tells you that your scan was clean or a virus was detected.
Here is some sample code,
FileController.cs
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Logging;
- using nClam;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Threading.Tasks;
-
- namespace ScanFiles_AntiVirus.Controllers
- {
- [Route("api/[controller]")]
- [ApiController]
- public class FileUploadController : ControllerBase
- {
- private readonly IConfiguration _configuration;
- public FileUploadController(
- IConfiguration configuration)
- {
- _configuration = configuration;
- }
-
- [HttpPost]
- public async Task<IActionResult> UploadFile(IFormFile file)
- {
- if (file == null || file.Length == 0)
- return Content("file not selected");
-
- var ms = new MemoryStream();
- file.OpenReadStream().CopyTo(ms);
- byte[] fileBytes = ms.ToArray();
- string Result = string.Empty;
- try
- {
- var clam = new ClamClient(this._configuration["ClamAVServer:URL"],
- Convert.ToInt32(this._configuration["ClamAVServer:Port"]));
- var scanResult = await clam.SendAndScanFileAsync(fileBytes);
-
-
- Result = scanResult.Result switch
- {
- ClamScanResults.Clean => "Clean",
- ClamScanResults.VirusDetected => "Virus Detected",
- ClamScanResults.Error => "Error in File",
- ClamScanResults.Unknown => "Unknown File",
- _ => "No case available"
- };
- }
- catch (Exception ex)
- {
- throw ex;
- }
-
- return Ok(Result);
- }
- }
- }
Run and Test with Valid File,
Test with Anti-malware 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 this
Site. You may need to pause your antivirus protection on your device to perform this activity.
Using their own Clam Av Ip address to scan our files
To scan the documents without docker image and if the clam av server is already installed in our machine we need to change a bit of code in the API level instead of going with docker port.
Here is the following code,
FileController.cs
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Logging;
- using nClam;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Threading.Tasks;
-
- namespace ScanFiles_AntiVirus.Controllers
- {
- [Route("api/[controller]")]
- [ApiController]
- public class FileUploadController : ControllerBase
- {
- private readonly IConfiguration _configuration;
- public FileUploadController(
- IConfiguration configuration)
- {
- _configuration = configuration;
- }
-
- [HttpPost]
- public async Task<IActionResult> UploadFile(IFormFile file)
- {
- if (file == null || file.Length == 0)
- return Content("file not selected");
-
- var ms = new MemoryStream();
- file.OpenReadStream().CopyTo(ms);
- byte[] fileBytes = ms.ToArray();
- string Result = string.Empty;
- try
- {
-
-
-
-
-
- var clam = new ClamClient(IPAddress.Parse("127.0.0.1"), 3310);
- var scanResult = await clam.SendAndScanFileAsync(fileBytes);
-
-
- Result = scanResult.Result switch
- {
- ClamScanResults.Clean => "Clean",
- ClamScanResults.VirusDetected => "Virus Detected",
- ClamScanResults.Error => "Error in File",
- ClamScanResults.Unknown => "Unknown File",
- _ => "No case available"
- };
- }
- catch (Exception ex)
- {
- throw ex;
- }
-
- return Ok(Result);
- }
- }
- }
Conclusion
Thank you for reading, please let me know your questions, thoughts, or feedback in the comments section. I appreciate your feedback and encouragement.
keep learning....!