Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tissue Laravel Package

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).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. 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.

  2. Install ClamAV: Ensure ClamAV is installed on your server:

    sudo apt-get install clamav clamav-daemon
    sudo freshclam  # Update virus definitions
    
  3. 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,
    ],
    
  4. 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!');
        }
    }
    

Implementation Patterns

Workflows

1. File Upload Validation

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()}");
}

2. Event-Driven Scanning

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));
    }
}

3. Queue-Based Scans

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));
    }
}

4. Facade for Cleaner Syntax

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
}

Integration Tips

1. Storage Integration

  • Local Filesystem: Scan files before moving them to permanent storage.
  • Cloud Storage (S3): Stream files to a temporary local path, scan, then upload to S3.
    $tempPath = tempnam(sys_get_temp_dir(), 'upload_');
    file_put_contents($tempPath, $file->get());
    $result = app(Scanner::class)->scan($tempPath);
    unlink($tempPath);
    

2. Middleware for API Protection

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);
}

3. Logging and Auditing

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(),
    ]);
});

4. Caching Scan Results

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);
}

Gotchas and Tips

Pitfalls

1. ClamAV Installation and Configuration

  • Missing Dependencies: Ensure clamav and clamav-daemon are installed. On Ubuntu/Debian:
    sudo apt-get install clamav clamav-daemon libclamav-dev
    
  • Daemon Not Running: Start the ClamAV daemon:
    sudo systemctl start clamav-daemon
    
  • Permission Issues: Ensure the PHP process has access to ClamAV’s socket (default: /var/run/clamav/clamd.ctl).

2. False Positives/Negatives

  • Legitimate Files Flagged: Some files (e.g., compressed archives, certain PDFs) may trigger false positives. Test thoroughly with your expected file types.
  • New Malware: Outdated ClamAV signatures may miss new threats. Schedule regular updates:
    sudo freshclam
    

3. File Execution Risks

  • Never Serve Scanned Files Directly: Even "clean" files could be malicious if executed. Store files outside the web root or use a CDN with strict MIME type checks.
  • Avoid Dynamic Execution: Never use eval(), include(), or file_get_contents() on uploaded files, even if scanned.

4. Performance Overhead

  • Large Files: Scanning large files (e.g., videos) can block requests. Use queues or async processing.
  • High Traffic: ClamAV scans are CPU-intensive. Consider:
    • Dedicated scan servers.
    • Caching results for identical files.
    • Rate-limiting scans.

5. Package Limitations

  • No Multi-Engine Support: Only ClamAV is supported. For broader coverage, consider:
    • Combining with other tools (e.g., VirusTotal API).
    • Forking the package to add adapters (e.g., for php-clamav or other scanners).
  • Stale Codebase: The package is unmaintained. Expect compatibility issues with PHP 8+ or Laravel 9+. Mitigate by:
    • Wrapping ClamAV CLI calls directly if needed.
    • Forking and updating the package.

Debugging

1. ClamAV Connection Issues

  • Check Daemon Status:
    sudo systemctl status clamav-daemon
    
  • Test ClamAV CLI:
    clamscan /path/to/file
    
  • Logs: Check ClamAV logs at /var/log/clamav/ for errors.

2. Scan Failures

  • Log Scan Output: Extend the 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)]);
    

3. False Positives

  • Whitelist Files: If certain files are falsely flagged, consider:
    • Skipping scans for known-safe file types (e.g., .jpg, .png).
    • Adding exceptions in your application logic.
  • ClamAV Config: Adjust ClamAV’s heuristic settings in /etc/clamav/clamd.conf (e.g., HeuristicScanPrecedence).

Tips

1. Configuration

  • Custom ClamAV Path: If ClamAV is not in the default path, configure it in
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
sandermuller/package-boost-php
sandermuller/boost-core
depa/sulu-google-reviews-bundle
croct/plug-symfony
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard