bubnov/tissue
Scan uploaded files for viruses in PHP via adapter-based integrations. Includes a ClamAV adapter to run ClamAV scans and report infected files, helping you add antivirus checks to your upload pipeline (keep signatures updated; follow upload security best practices).
Install the Package:
composer require cleentfaar/tissue
Note: The package name in the repo is cleentfaar/tissue, not bubnov/tissue as per the prompt. Adjust accordingly.
Install ClamAV: Ensure ClamAV is installed on your server:
sudo apt-get install clamav clamav-daemon
sudo freshclam # Update virus definitions
Basic Usage: Create a service provider to bind the scanner:
// app/Providers/TissueServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Tissue\Scanner;
use Tissue\Adapter\ClamAvAdapter;
class TissueServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Scanner::class, function ($app) {
return new Scanner(new ClamAvAdapter());
});
}
}
Register the provider in config/app.php:
'providers' => [
// ...
App\Providers\TissueServiceProvider::class,
],
First Scan: Use the scanner in a controller or service:
use Tissue\Scanner;
public function uploadFile(Request $request)
{
$file = $request->file('file');
$path = $file->store('uploads');
$scanner = app(Scanner::class);
$result = $scanner->scan($path);
if ($result->isClean()) {
// Process clean file
} else {
return back()->withError('Malware detected!');
}
}
Integrate scanning into Laravel’s file upload pipeline:
// app/Http/Requests/StoreFileRequest.php
public function handle()
{
$file = $this->file('file');
$path = $file->store('uploads/temp');
$scanner = app(Scanner::class);
$result = $scanner->scan($path);
if (!$result->isClean()) {
$this->fail('Malware detected in upload.');
}
// Move to permanent storage if clean
Storage::move("uploads/temp/{$file->hashName()}", "uploads/{$file->hashName()}");
}
Trigger scans via Laravel events (e.g., file.uploaded):
// app/Listeners/ScanUploadedFile.php
public function handle(FileUploaded $event)
{
$scanner = app(Scanner::class);
$result = $scanner->scan($event->filePath);
if (!$result->isClean()) {
event(new MalwareDetected($event->filePath));
}
}
Offload scans to a queue for large files:
// app/Jobs/ScanFileJob.php
public function handle()
{
$scanner = app(Scanner::class);
$result = $scanner->scan($this->filePath);
if (!$result->isClean()) {
Storage::delete($this->filePath);
event(new MalwareDetected($this->filePath));
}
}
Create a facade to simplify usage:
// app/Facades/VirusScanner.php
public static function scan($path)
{
return app(Scanner::class)->scan($path);
}
Usage:
if (!VirusScanner::scan($path)->isClean()) {
// Handle malware
}
$tempPath = tempnam(sys_get_temp_dir(), 'upload_');
file_put_contents($tempPath, $file->get());
$result = app(Scanner::class)->scan($tempPath);
unlink($tempPath);
Add middleware to scan files in incoming requests:
// app/Http/Middleware/ScanUploads.php
public function handle($request, Closure $next)
{
if ($request->hasFile('file')) {
$path = $request->file('file')->store('temp');
$result = app(Scanner::class)->scan($path);
if (!$result->isClean()) {
Storage::delete($path);
return response()->json(['error' => 'Malware detected'], 400);
}
}
return $next($request);
}
Log scan results for compliance:
$scanner->scan($path)->then(function ($result) use ($path) {
\Log::info('File scanned', [
'path' => $path,
'clean' => $result->isClean(),
'virus' => $result->getVirusName(),
]);
});
Cache results for identical files (e.g., using file hashes):
$hash = hash_file('sha256', $path);
$cached = cache()->get("scan:{$hash}");
if (!$cached) {
$result = app(Scanner::class)->scan($path);
cache()->put("scan:{$hash}", $result->isClean(), now()->addHours(1));
} else {
$result = new \Tissue\Result($cached);
}
clamav and clamav-daemon are installed. On Ubuntu/Debian:
sudo apt-get install clamav clamav-daemon libclamav-dev
sudo systemctl start clamav-daemon
/var/run/clamav/clamd.ctl).sudo freshclam
eval(), include(), or file_get_contents() on uploaded files, even if scanned.php-clamav or other scanners).sudo systemctl status clamav-daemon
clamscan /path/to/file
/var/log/clamav/ for errors.ClamAvAdapter to log raw ClamAV output:
// In ClamAvAdapter::scan()
exec("clamscan --no-summary --stdout {$path} 2>&1", $output, $return);
\Log::debug('ClamAV output', ['output' => implode("\n", $output)]);
.jpg, .png)./etc/clamav/clamd.conf (e.g., HeuristicScanPrecedence).How can I help you explore Laravel packages today?