PHPackages                             jodeveloper/upload-file-scanner - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. jodeveloper/upload-file-scanner

ActiveLibrary[Security](/categories/security)

jodeveloper/upload-file-scanner
===============================

A Laravel package for scanning uploaded files using ClamAV

1.0.1(3mo ago)10[2 PRs](https://github.com/JoDeveloper/upload-file-scanner/pulls)MITPHPPHP ^8.3CI passing

Since Feb 3Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/JoDeveloper/upload-file-scanner)[ Packagist](https://packagist.org/packages/jodeveloper/upload-file-scanner)[ Docs](https://github.com/jodeveloper/upload-file-scanner)[ GitHub Sponsors](https://github.com/:vendor_name)[ RSS](/packages/jodeveloper-upload-file-scanner/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (15)Versions (5)Used By (0)

Laravel ClamAV Upload Scanner
=============================

[](#laravel-clamav-upload-scanner)

 [![Laravel ClamAV Upload Scanner](logo.png)](logo.png)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2b836ccbc365f8b72cf59763012633765e711d3108ab2efc9ca6e256fe491290/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a6f646576656c6f7065722f75706c6f61642d66696c652d7363616e6e65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/jodeveloper/upload-file-scanner)[![Total Downloads](https://camo.githubusercontent.com/868f380b49d0265d0198b2ec40750b0654d4792d38c6e260ceed52011c753222/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6a6f646576656c6f7065722f75706c6f61642d66696c652d7363616e6e65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/jodeveloper/upload-file-scanner)

A clean, Laravel-native way to scan uploaded files using ClamAV. This package provides a simple API for virus scanning in your file upload validation and storage pipelines.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require jodeveloper/upload-file-scanner
```

You can publish the config file with:

```
php artisan vendor:publish --tag="clamav-scanner-config"
```

This is the contents of the published config file:

```
return [
    'binary' => env('CLAMAV_BINARY', 'clamscan'),
    'timeout' => (int) env('CLAMAV_TIMEOUT', 30),
    'scan_options' => [
        '--no-summary',
    ],
];
```

Requirements
------------

[](#requirements)

- PHP 8.3 or higher
- Laravel 11.0 or 12.0
- ClamAV installed on your server (clamscan binary)

Installing ClamAV
-----------------

[](#installing-clamav)

### macOS

[](#macos)

```
brew install clamav
```

After installation, you may need to update the virus definitions:

```
freshclam
```

### Ubuntu/Debian

[](#ubuntudebian)

```
sudo apt-get update
sudo apt-get install clamav clamav-daemon
```

Update virus definitions:

```
sudo freshclam
```

### CentOS/RHEL

[](#centosrhel)

```
sudo yum install epel-release
sudo yum install clamav clamav-update
```

Update virus definitions:

```
sudo freshclam
```

### From Source

[](#from-source)

For detailed instructions on installing ClamAV from source, see the [official ClamAV documentation](https://docs.clamav.net/manual/Installing/Installing-from-source-Unix.html).

### Verifying Installation

[](#verifying-installation)

After installation, verify that ClamAV is accessible:

```
clamscan --version
```

This should display ClamAV version information.

Usage
-----

[](#usage)

### Using the Facade (Recommended)

[](#using-the-facade-recommended)

```
use Jodeveloper\UploadFileScanner\Facades\Scanner;

$result = Scanner::scan('/path/to/file');

if ($result->hasVirus()) {
    // Handle infected file
}

if ($result->isClean()) {
    // File is safe to process
}

// Get the scanner output
$output = $result->output;
```

### Using the Validation Rule

[](#using-the-validation-rule)

The package provides a Laravel validation rule for easy integration:

**Simple approach (recommended):**

```
public function upload(Request $request)
{
    $validated = $request->validate([
        'file' => ['required', 'file', 'clean_file'],
    ]);

    // File is clean, proceed with storage
}
```

**For more control, use the object-based approach:**

```
use Jodeveloper\UploadFileScanner\Rules\CleanFile;
use Jodeveloper\UploadFileScanner\Contracts\Scanner;

public function upload(Request $request)
{
    $validated = $request->validate([
        'file' => ['required', 'file', new CleanFile()],
    ]);

    // File is clean, proceed with storage
}
```

### Example Controller

[](#example-controller)

```
use Illuminate\Http\Request;
use Jodeveloper\UploadFileScanner\Contracts\Scanner;
use Jodeveloper\UploadFileScanner\Exceptions\ScanFailedException;

class FileUploadController extends Controller
{
    public function store(Request $request, Scanner $scanner)
    {
        $request->validate([
            'file' => ['required', 'file', 'max:10240'], // max 10MB
        ]);

        try {
            $result = $scanner->scan($request->file('file')->getRealPath());

            if ($result->hasVirus()) {
                return back()->with('error', 'The uploaded file contains a virus.');
            }

            // File is clean, store it
            $path = $request->file('file')->store('uploads');

            return back()->with('success', 'File uploaded successfully.');

        } catch (ScanFailedException $e) {
            // Handle scanner execution failure
            return back()->with('error', 'Unable to scan file. Please try again.');
        }
    }
}
```

Configuration
-------------

[](#configuration)

### ClamAV Binary Path

[](#clamav-binary-path)

By default, the package assumes `clamscan` is in your system PATH. If you have a custom installation:

```
CLAMAV_BINARY=/usr/local/bin/clamscan
```

### Scan Timeout

[](#scan-timeout)

The default timeout is 30 seconds. Adjust for large files:

```
CLAMAV_TIMEOUT=60
```

### Scan Options

[](#scan-options)

Add additional options to pass to clamscan in the config file:

```
'scan_options' => [
    '--no-summary',
    '--infected',
],
```

**Warning:** Use caution with options like `--remove` which will delete infected files.

Security Philosophy
-------------------

[](#security-philosophy)

### This Package is a Secondary Defense

[](#this-package-is-a-secondary-defense)

This package provides virus scanning as a secondary security layer. It should **not** be your only defense against malicious file uploads.

### Required Additional Security Measures

[](#required-additional-security-measures)

1. **Re-encoding Images**: Always re-encode uploaded images to strip potential embedded payloads
2. **File Type Validation**: Validate MIME types and file extensions
3. **Content Inspection**: Inspect file contents, not just extensions
4. **Storage Location**: Store uploads outside of the public web root
5. **Access Control**: Implement proper authentication and authorization

### SVG Files are Unsafe

[](#svg-files-are-unsafe)

SVG files can contain JavaScript and should be treated with extreme caution. Always sanitize SVG files before storage or serving.

### Public Storage is Dangerous

[](#public-storage-is-dangerous)

Never store user uploads in publicly accessible directories without proper access controls. Use Laravel's `Storage::disk('local')` or implement signed URLs for public access.

Exception Handling
------------------

[](#exception-handling)

The package throws `ScanFailedException` when:

- ClamAV binary is not found
- Process crashes or fails to execute
- Timeout occurs
- Other execution errors occur

Infected files do **not** throw exceptions. They return a `ScanResult` where `hasVirus()` returns `true`.

```
use Jodeveloper\UploadFileScanner\Exceptions\ScanFailedException;

try {
    $result = $scanner->scan($path);
} catch (ScanFailedException $e) {
    // Log the error and notify administrators
    Log::error('ClamAV scan failed', ['message' => $e->getMessage()]);
    throw new \RuntimeException('Unable to scan file. Please try again later.');
}
```

API Reference
-------------

[](#api-reference)

### Facade

[](#facade)

```
use Jodeveloper\UploadFileScanner\Facades\Scanner;

Scanner::scan(string $path): ScanResult
```

### Contract

[](#contract)

```
use Jodeveloper\UploadFileScanner\Contracts\Scanner;

public function __construct(Scanner $scanner)
```

### ScanResult

[](#scanresult)

The `ScanResult` object is immutable and exposes readonly properties:

```
public readonly bool $clean
public readonly string $output
```

Helper methods are also available:

```
isClean(): bool     // Returns true if no virus was found
hasVirus(): bool    // Returns true if a virus was detected
```

### CleanFile Rule

[](#cleanfile-rule)

Implements `Illuminate\Contracts\Validation\Rule`. Can be used as an object or string rule (`clean_file`).

Testing
-------

[](#testing)

```
composer test
```

The test suite mocks all ClamAV execution - no actual scanning occurs during tests.

Limitations
-----------

[](#limitations)

- This package does not provide automatic scanning of all uploads
- No UI is included
- No opinionated storage logic is provided
- ClamAV must be installed and accessible on your server

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Joe Developer](https://github.com/jodeveloper)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance86

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

2

Last Release

103d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/90a228b8f28fb5cf07826b801bb52e14e8b673b4f1f1f1ff65b4eca8519eba80?d=identicon)[JoDeveloper08](/maintainers/JoDeveloper08)

---

Top Contributors

[![JoDeveloper](https://avatars.githubusercontent.com/u/18007194?v=4)](https://github.com/JoDeveloper "JoDeveloper (25 commits)")

---

Tags

laravelclamavjodeveloperfile-scannervirus-scanner

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/jodeveloper-upload-file-scanner/health.svg)

```
[![Health](https://phpackages.com/badges/jodeveloper-upload-file-scanner/health.svg)](https://phpackages.com/packages/jodeveloper-upload-file-scanner)
```

###  Alternatives

[spatie/laravel-health

Monitor the health of a Laravel application

86910.0M83](/packages/spatie-laravel-health)[spatie/laravel-ciphersweet

Use ciphersweet in your Laravel project

416718.4k1](/packages/spatie-laravel-ciphersweet)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[keepsuit/laravel-temporal

Laravel temporal.io

4875.0k](/packages/keepsuit-laravel-temporal)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
