在存储文件之前,如何检查上传的文件是否存在病毒?
我之前读过这个话题,但如何以编程方式实现并向用户返回结果?
避免任何类型的用户上传文件问题的最佳方法是,在服务器上安装命令行病毒扫描程序,在上传后使用它来扫描文件。如果扫描结果是阳性的,则删除该文件等。
在存储文件之前,如何检查上传的文件是否存在病毒?
我之前读过这个话题,但如何以编程方式实现并向用户返回结果?
避免任何类型的用户上传文件问题的最佳方法是,在服务器上安装命令行病毒扫描程序,在上传后使用它来扫描文件。如果扫描结果是阳性的,则删除该文件等。
为了让您的生活更轻松……请查看Metascan Online。他们提供一个在线免费公共API。将来,您还可以通过Metascan Online公共API设置以编程方式执行此操作的方法。
Sample Code(PHP)
// Config.
$api = 'https://api.metascan-online.com/v1/file';
$apikey = 'E1D7-DG5E-4FE0-BFAE';
$file = 'test.txt';
// Build headers array.
$headers = array(
'apikey: '.$apikey,
'filename: '.basename($file)
);
// Build options array.
$options = array(
CURLOPT_URL => $api,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => file_get_contents($file),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false
);
// Init & execute API call.
$ch = curl_init();
curl_setopt_array($ch, $options);
$response = json_decode(curl_exec($ch), true);
print_r($response);
我对此主题进行了一些研究,以下是摘要。(主要针对Windows和C#,因为我使用的是Windows操作系统,并且我们正在使用Symantec防病毒软件)
Symantec产品:
a. Systemtec扫描引擎: 它类似于一个私有的反病毒服务,并提供SDK以集成到您的系统中。
b. Doscan.exe: 这是一个命令行工具,我可以在我们公司的系统中找到。我们可以通过创建新进程来在代码中使用它来扫描文件。它使用Symantec扫描器相同的扫描过程。因此,在软件执行长时间扫描时会被阻止。
反病毒扫描程序
这个库是反病毒软件产品(如“Microsoft Security Essentials (Windows Defender)”)的包装器,它安装在您的Windows操作系统上。由于我无法停止我的机器上Symantec的实时扫描,所以不知道它是否有效。我发现有用户说它不起作用,但我没有检查。
Windows Defender :
它是内置于Windows系统中的反病毒软件。据说它有一个命令行工具(mpcmdrun.exe),但我在我的机器上找不到它。由于我们正在使用Symantec,它被禁用了。如果您有它,可以试试。
开源反病毒产品
ClamAV是一个流行的开源反病毒产品。一些产品将其集成到他们的系统中。它还有C# API,因此也可以用来制作私有云扫描引擎。
商业扫描引擎开放API,例如: Virustotal和Sophos。
尝试使用像virusTotal或类似的在线资源进行扫描。 另外我知道卡巴斯基有一个在线扫描器,但目前不可用。
从应用程序角度来看,您可以创建代理服务器,在此服务器上安装防病毒软件,将文件上传到该服务器上,进行扫描并传输到目标服务器。
HttpPostedFileBase.InputStream
,并将其发送到ClamAv进行扫描。 在MVC中,几乎没有代码可以让它工作,非常简单。/// Main controller
public class HomeController : Controller {
/// Get the upload view
[HttpGet]
public ActionResult Index() {
return View();
}
/// Handle the file upload
[HttpPost]
public ActionResult Index(UploadViewModel model, HttpPostedFileBase file) {
var scanner = VirusScannerFactory.GetVirusScanner();
var result = scanner.ScanStream(file.InputStream);
if(result.IsVirusFree) {
// save to disk
} else {
// don't save to disk and tell user they uploaded a virus
}
return View(model);
}
}
public class VirusScannerFactory {
public static IScanViruses GetVirusScanner() {
//Currently we only have one Antivirus implementation,
//but later we want to include AVG, SOPHOS and metascan
return new ClamAvScanner();
}
}
public interface IScanViruses {
ScanResult ScanFile(string fullPath);
ScanResult ScanBytes(byte[] bytes);
ScanResult ScanStream(Stream stream);
}
public class ClamAvScanner : IScanViruses{
... snip ...
/// Scans your data stream for virus
public ScanResult ScanStream(Stream stream) {
var clam = new ClamClient("localhost", 3310);
return MapScanResult(clam.SendAndScanFile(stream));
}
...snip ...
/// helper method to map scan result
private ScanResult MapScanResult(ClamScanResult scanResult) {
var result = new ScanResult();
switch (scanResult.Result) {
case ClamScanResults.Unknown:
result.Message = "Could not scan file";
result.IsVirusFree = false;
break;
case ClamScanResults.Clean:
result.Message = "No Virus found";
result.IsVirusFree = true;
break;
case ClamScanResults.VirusDetected:
result.Message = "Virus found: " + scanResult.InfectedFiles.First().VirusName;
result.IsVirusFree = false;
break;
case ClamScanResults.Error:
result.Message = string.Format("VIRUS SCAN ERROR! {0}", scanResult.RawResult);
result.IsVirusFree = false;
break;
}
return result;
}
}