ikechukwukalu/clamavfileupload

使用ClamAV进行文件上传病毒扫描

v3.0.1 2024-06-18 08:17 UTC

README

Latest Version on Packagist Quality Score Code Quality Known Vulnerabilities Github Workflow Status Total Downloads Licence

这是一个简单的具有ClamAV病毒扫描功能的文件上传Laravel包。这个库是在现有的clamav php库 kissit/php-clamav-scan 上构建的。

要求

  • PHP 8.0+
  • Laravel 9+
  • Clamav

安装步骤

composer require ikechukwukalu/clamavfileupload
  • php artisan vendor:publish --tag=cfu-config
CLAMD_SOCK="/var/run/clamav/clamd.sock"
CLAMD_SOCK_LEN=20000
CLAMD_IP=null
CLAMD_PORT=3310
FILE_UPLOAD_INPUT=file
FILE_UPLOAD_DISK=public
FILE_UPLOAD_LOG_SCAN_DATA=false
HASHED=false
VISIBLE=true
  • php artisan vendor:publish --tag=cfu-migrations
  • php artisan migrate

CLAMAV病毒扫描文件上传

use Ikechukwukalu\Clamavfileupload\Facades\Services\FileUpload;


FileUpload::uploadFiles($request); //returns bool|FileUploadModel|EloquentCollection

/**
 * Default settings
 *
 * 'name' => null // This is different from file name
 * 'input' => config('clamavfileupload.input', 'file')
 * 'folder' => null
 * 'hashed' => config('clamavfileupload.hashed', false)
 * 'visible' => config('clamavfileupload.visible', true)
 * 'disk' => config('clamavfileupload.disk', 'local')
 *
 *
 */

/**
 * You can also overwrite the default settings with custom settings
 */
$settings = [
    'folder' => 'pdfs'
];

$fileUpload = new FileUpload;
$fileUpload::uploadFiles($request, $settings); //returns bool|FileUploadModel|EloquentCollection

/**
 * Access last scan results
 */
$fileUpload::getScanData()

/**
 * Check if upload was successful
 */
if (!$fileUpload::isSuccessful()) {
    echo $fileUpload::getErrorMessage();
}

/**
 * Make sure to save the $ref UUID so as to be
 * able to retrieve the uploaded file(s) from the database.
 */
$fileUpload::getRef()

/**
 * Soft delete files
 */

/**
 * @param string $ref
 * @return bool
 */
FileUpload::deleteAll($ref);

/**
 * @param array $ids
 * @param string $ref
 * @return bool
 */
FileUpload::deleteMultiple($ids, $ref);

/**
 * @param int $id
 * @param string $ref
 * @return bool
 */
FileUpload::deleteOne($id, $ref);


/**
 * Permanently delete files from the database and disk
 */

/**
 * @param string $ref
 * @return bool
 */
FileUpload::forceDeleteAll($ref);

/**
 * @param array $ids
 * @param string $ref
 * @return bool
 */
FileUpload::forceDeleteMultiple($ids, $ref);

/**
 * @param int $id
 * @param string $ref
 * @return bool
 */
FileUpload::forceDeleteOne($id, $ref);

队列中的CLAMAV病毒扫描文件上传

此过程将文件存储在tmp目录中,并为clamav扫描设置队列,并将tmp文件上传到指定的目录。在过程结束时,临时文件将从tmp目录中删除。

  • 要使用Redis,请在您的.env文件中设置REDIS_CLIENT=predisQUEUE_CONNECTION=redis
  • php artisan queue:work
use Ikechukwukalu\Clamavfileupload\Facades\Services\QueuedFileUpload;


QueuedFileUpload::uploadFiles($request); //returns bool|FileUploadModel|EloquentCollection

/**
 * Default settings
 *
 * 'name' => null // This is different from file name
 * 'input' => config('clamavfileupload.input', 'file')
 * 'folder' => null
 * 'hashed' => config('clamavfileupload.hashed', false)
 * 'visible' => config('clamavfileupload.visible', true)
 * 'disk' => config('clamavfileupload.disk', 'local')
 *
 *
 */

/**
 * You can also overwrite the default settings with custom settings
 */
$settings = [
    'folder' => 'pdfs'
];

$fileUpload = new QueuedFileUpload;
$fileUpload::uploadFiles($request, $settings); //returns bool|FileUploadModel|EloquentCollection

/**
 * Make sure to save the $ref UUID so as to be
 * able to retrieve the uploaded file(s) from the database.
 */
$fileUpload::getRef()

/**
 * Soft delete files
 */

/**
 * @param string $ref
 * @return bool
 */
QueuedFileUpload::deleteAll($ref);

/**
 * @param array $ids
 * @param string $ref
 * @return bool
 */
QueuedFileUpload::deleteMultiple($ids, $ref);

/**
 * @param int $id
 * @param string $ref
 * @return bool
 */
QueuedFileUpload::deleteOne($id, $ref);


/**
 * Permanently delete files from the database and disk
 */

/**
 * @param string $ref
 * @return bool
 */
QueuedFileUpload::forceDeleteAll($ref);

/**
 * @param array $ids
 * @param string $ref
 * @return bool
 */
QueuedFileUpload::forceDeleteMultiple($ids, $ref);

/**
 * @param int $id
 * @param string $ref
 * @return bool
 */
QueuedFileUpload::forceDeleteOne($id, $ref);

无CLAMAV病毒扫描文件上传

use Ikechukwukalu\Clamavfileupload\Facades\Services\NoClamavFileUpload;


NoClamavFileUpload::uploadFiles($request); //returns bool|FileUploadModel|EloquentCollection

/**
 * Default settings
 *
 * 'name' => null // This is different from file name
 * 'input' => config('clamavfileupload.input', 'file')
 * 'folder' => null
 * 'hashed' => config('clamavfileupload.hashed', false)
 * 'visible' => config('clamavfileupload.visible', true)
 * 'disk' => config('clamavfileupload.disk', 'local')
 *
 *
 */

/**
 * You can also overwrite the default settings with custom settings
 */
$settings = [
    'folder' => 'pdfs'
];

$fileUpload = new NoClamavFileUpload;
$fileUpload::uploadFiles($request, $settings); //returns bool|FileUploadModel|EloquentCollection

/**
 * Check if upload was successful
 */
if (!$fileUpload::isSuccessful()) {
    echo $fileUpload::getErrorMessage();
}

/**
 * Make sure to save the $ref UUID so as to be
 * able to retrieve the uploaded file(s) from the database.
 */
$fileUpload::getRef()

/**
 * Soft delete files
 */

/**
 * @param string $ref
 * @return bool
 */
NoClamavFileUpload::deleteAll($ref);

/**
 * @param array $ids
 * @param string $ref
 * @return bool
 */
NoClamavFileUpload::deleteMultiple($ids, $ref);

/**
 * @param int $id
 * @param string $ref
 * @return bool
 */
NoClamavFileUpload::deleteOne($id, $ref);


/**
 * Permanently delete files from the database and disk
 */

/**
 * @param string $ref
 * @return bool
 */
NoClamavFileUpload::forceDeleteAll($ref);

/**
 * @param array $ids
 * @param string $ref
 * @return bool
 */
NoClamavFileUpload::forceDeleteMultiple($ids, $ref);

/**
 * @param int $id
 * @param string $ref
 * @return bool
 */
NoClamavFileUpload::forceDeleteOne($id, $ref);

哈希

如果您的.env文件中的HASHED参数设置为true,则在将它们保存到数据库之前,将加密file_namepathurl字段。存储的文件也将被加密。

扩展模型文件Ikechukwukalu\Clamavfileupload\Models\FileUpload并添加以下代码可能会有所帮助

use Illuminate\Support\Facades\Crypt;

    protected function getFileNameAttribute($value)
    {
        if ($this->hashed) {
            return Crypt::decryptString($value);
        }

        return $value;
    }

    protected function getPathAttribute($value)
    {
        if ($this->hashed) {
            return Crypt::decryptString($value);
        }

        return $value;
    }


    protected function getRelativePathAttribute($value)
    {
        if ($this->hashed) {
            return Crypt::decryptString($value);
        }

        return $value;
    }

    protected function getUrlAttribute($value)
    {
        if ($this->hashed) {
            return Crypt::decryptString($value);
        }

        return $value;
    }

查看和下载加密文件的示例代码

use Illuminate\Http\Request;
use Ikechukwukalu\Clamavfileupload\Models\FileUpload as FileUploadModel;
use Symfony\Component\HttpFoundation\StreamedResponse;

Route::get('/download/hashed/file/{id}', function (Request $request, $id): StreamedResponse {
    $file = FileUploadModel::where('id', $id)->first()

    return response()->streamDownload(function () use($file) {
        echo Crypt::decrypt(Storage::disk($file->disk)->get($file->relative_path));
    }, "{$file->name}{$file->extension}");
});

Route::get('/view/hashed/file/{id}', function (Request $request, $id) {
    $file = FileUploadModel::where('id', $id)->first();
    $decrypted = Crypt::decrypt(Storage::disk($file->disk)->get($file->relative_path));

    header("Content-type: {$file->mime_type}");
    echo $decrypted;
});

事件

/**
 * Dispatches when FileUpload::uploadFiles()
 * is called.
 *
 */
\Ikechukwukalu\Clamavfileupload\Events\ClamavFileScan::class

/**
 * Dispatches when QueuedFileUpload::uploadFiles()
 * is called.
 *
 * @param  array  $tmpFiles
 * @param  array  $settings
 * @param  string  $ref
 */
\Ikechukwukalu\Clamavfileupload\Events\ClamavQueuedFileScan::class

/**
 * Dispatches when all files scanned are safe.
 *
 * @param  array  $scanData
 */
\Ikechukwukalu\Clamavfileupload\Events\FileScanPass::class

/**
 * Dispatches when a file scanned has a problem.
 *
 * @param  array  $scanData
 */
\Ikechukwukalu\Clamavfileupload\Events\FileScanFail::class

/**
 * Dispatches when files have been stored and saved into the Database.
 *
 * @param  FileUploadModel|EloquentCollection $files
 * @param  string  $ref
 */
\Ikechukwukalu\Clamavfileupload\Events\SavedFilesIntoDB::class

/**
 * Dispatches when clamav is not running.
 *
 */
\Ikechukwukalu\Clamavfileupload\Events\ClamavIsNotRunning::class

/**
 * Dispatches when file soft delete fails.
 *
 * @param  array  $data
 */
\Ikechukwukalu\Clamavfileupload\Events\FileDeleteFail::class

/**
 * Dispatches when file soft delete passes.
 *
 * @param  array  $data
 */
\Ikechukwukalu\Clamavfileupload\Events\FileDeletePass::class

/**
 * Dispatches when permanent file delete from database and disk fails.
 *
 * @param  array  $data
 */
\Ikechukwukalu\Clamavfileupload\Events\FileForceDeleteFail::class

/**
 * Dispatches when permanent file delete from database and disk passes.
 *
 * @param  array  $data
 */
\Ikechukwukalu\Clamavfileupload\Events\FileForceDeletePass::class

/**
 * Dispatches when a QueuedFileUpload::deleteAll($ref) is called.
 *
 * @param  string  $ref
 */
\Ikechukwukalu\Clamavfileupload\Events\QueuedDeleteAll::class

/**
 * Dispatches when a QueuedFileUpload::deleteMultiple($ids, $ref) is called.
 *
 * @param  string  $ref
 * @param  array  $ids
 */
\Ikechukwukalu\Clamavfileupload\Events\QueuedDeleteMultiple::class

/**
 * Dispatches when a QueuedFileUpload::deleteOne($id, $ref) is called.
 *
 * @param  string  $ref
 * @param  int|string  $id
 */
\Ikechukwukalu\Clamavfileupload\Events\QueuedDeleteOne::class

/**
 * Dispatches when a QueuedFileUpload::forceDeleteAll($ref) is called.
 *
 * @param  string  $ref
 */
\Ikechukwukalu\Clamavfileupload\Events\QueuedForceDeleteAll::class

/**
 * Dispatches when a QueuedFileUpload::forceDeleteMultiple($ids, $ref) is called.
 *
 * @param  string  $ref
 * @param  array  $ids
 */
\Ikechukwukalu\Clamavfileupload\Events\QueuedForceDeleteMultiple::class

/**
 * Dispatches when a QueuedFileUpload::forceDeleteOne($id, $ref) is called.
 *
 * @param  string  $ref
 * @param  int|string  $id
 */
\Ikechukwukalu\Clamavfileupload\Events\QueuedForceDeleteOne::class

注意

  • 当单个文件扫描失败时,过程结束,并将删除所有上传的文件。
  • 每个上传文件批次都会分配一个$ref UUID。
  • 当使用s3磁盘时,文件首先存储在tmp目录中,使用local磁盘,然后在上传到s3存储桶之前进行扫描。
  • 始终在配置文件中将自定义的s3磁盘添加到s3_disk数组中。
  • 模型文件Ikechukwukalu\Clamavfileupload\Models\FileUpload
protected $fillable = [
    'ref',
    'name',
    'file_name',
    'size',
    'extension',
    'disk',
    'mime_type',
    'path',
    'url',
    'folder',
    'hashed',
];

发布语言

  • php artisan vendor:publish --tag=cfu-lang

许可证

CFU包是开源软件,根据MIT许可证授权。