Drivers
The ClamAV Driver
Scanning uploads and payloads for malware with ClamAV.
Introduction
The ClamAV driver lets your API scan file uploads and other payloads for malware using ClamAV's clamd daemon.
It speaks the clamd INSTREAM protocol over TCP, so byte blobs are scanned in memory without ever being written to disk. Like other Kipchak drivers, it supports multiple named connections.
Installation
Install the driver via composer by running:
composer require kipchak/driver-clamav
Initialise the Driver
Add the following line to your drivers/drivers.php file:
\Kipchak\Driver\ClamAV\ClamAV::initialise($container);
Configuration
The configuration in kipchak.clamav.php can be used to configure multiple clamd connections. Each key is a connection name, resolvable with ClamAV::get('<name>'):
use function Kipchak\Core\env;
return [
'default' => [
'host' => env('CLAMAV_HOST', '127.0.0.1'),
'port' => (int) env('CLAMAV_PORT', '3310'),
'timeout' => (float) env('CLAMAV_TIMEOUT_SECONDS', '30'),
],
];
clamd listens on TCP port 3310 by default.
Usage
Scanning content
use Kipchak\Driver\ClamAV\ClamAV;
$result = ClamAV::get('default')->scan($uploadedFile->getStream()->getContents());
if (!$result->isClean()) {
// Reject the upload. The matched signature name is available:
$signature = $result->getSignature(); // e.g. "Eicar-Test-Signature"
}
scan() returns a ScanResult with two methods: isClean() and getSignature() (which is null for clean content).
Health checks
$healthy = ClamAV::get('default')->ping(); // true when clamd answers PONG
Failing open or closed
If clamd cannot be reached, scan() throws Kipchak\Driver\ClamAV\Exception\ConnectionException. The driver deliberately does not decide what happens next — catch the exception and choose whether an unreachable scanner rejects the upload (fail closed) or lets it through (fail open) for your use case:
use Kipchak\Driver\ClamAV\Exception\ConnectionException;
try {
$result = ClamAV::get('default')->scan($bytes);
} catch (ConnectionException $e) {
// Fail closed: treat an unreachable scanner as a rejection.
return $this->response($response, ['error' => 'Upload could not be scanned'], 503);
}
Testing your own code
The client implements Kipchak\Driver\ClamAV\ScannerInterface, so you can inject a fake scanner in your tests without running a clamd daemon. For live testing, use the EICAR test signature.
Git Repository
The source code for this driver is available on 1x.ax at https://1x.ax/mamluk/kipchak/drivers/clamav.