artisanpack-ui / secure-uploads
File upload security for Laravel — content-type validation, filename sanitization, malware scanning (ClamAV / VirusTotal), rate limiting, secure storage, and quarantine.
Requires
- php: ^8.2
- artisanpack-ui/core: ^1.0
- illuminate/support: ^10.0|^11.0|^12.0
- symfony/mime: ^6.0|^7.0
Requires (Dev)
- artisanpack-ui/code-style: ^1.1
- artisanpack-ui/code-style-pint: ^1.1
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- friendsofphp/php-cs-fixer: ^3.75
- laravel/pint: ^1.26
- orchestra/testbench: ^10.2
- pestphp/pest: ^3.8
- pestphp/pest-plugin-laravel: ^3.2
README
File upload security for Laravel: content-type validation with magic-byte sniffing, filename sanitization, pluggable malware scanning (ClamAV / VirusTotal), secure signed-URL storage, upload rate limiting, and quarantine workflows.
This package is part of the ArtisanPack UI Security 2.0 split — the upload-focused features previously bundled inside artisanpack-ui/security (1.x) live here in 2.0+.
Features
- File validation pipeline (
FileValidationService) — MIME sniffing against actual file content, magic-byte verification, extension allowlists / blocklists, per-type and absolute size limits, double-extension and null-byte trick detection, EXIF stripping for images - Validation rules —
SafeFilename,SecureFile(drop-inRuleclasses for Form Requests) - Pluggable malware scanning —
ClamAvScanner(Unix socket or binary),VirusTotalScanner(API + by-hash short-circuit),NullScanner(dev / CI default) - Secure storage (
SecureFileStorageService) — files stored outside the public root, served only via signed URLs through the bundledSecureFileController - Quarantine workflow — files flagged by async scanning live in a quarantine area until cleared by
security:scan-quarantine - Upload rate limiting (
FileUploadRateLimiter) - Middleware —
validate.upload,scan.upload - Eloquent concern —
HasSecureFilesaddsattachSecureFile,secureImages,secureDocuments, etc. to any model that owns uploaded files - Events —
FileUploaded,FileUploadRejected,FileServed,MalwareDetected(subscribed to byartisanpack-ui/security-analyticsfor audit trail) - Artisan commands —
security:cleanup-files,security:scan-quarantine
Installation
composer require artisanpack-ui/secure-uploads php artisan migrate
(Optional) Publish the config:
php artisan vendor:publish --tag=secure-uploads-config
Quick start
use ArtisanPackUI\SecureUploads\Concerns\HasSecureFiles; class Post extends Model { use HasSecureFiles; }
$post = Post::find(1); $stored = $post->attachSecureFile($request->file('attachment')); return redirect()->route('secure-file.show', ['identifier' => $stored->identifier]);
The attachSecureFile() call runs validation, optionally scans for malware, sanitizes the filename, and stores the file behind a signed URL.
Configuration
The shipped config covers MIME / extension allow- and block-lists, size limits, EXIF stripping, scanner driver selection (null / clamav / virustotal), and rate limiting. Override any of it after publishing:
php artisan vendor:publish --tag=secure-uploads-config
See config/artisanpack/secure-uploads.php for the full list with inline documentation.
Documentation
- Documentation home — overview + map
- Getting started — 5-minute install + first upload
- Installation — requirements, configuration, scanner setup
- Usage — validation, malware scanning, storage, signed URLs, events, commands
- Advanced — extending validators, custom scanners, quarantine workflow
- FAQ
- Troubleshooting
- Changelog
Requirements
- PHP 8.2+
- Laravel 10 / 11 / 12
ext-fileinfo(bundled with PHP) for MIME detection- ClamAV daemon or binary (optional, only if using the ClamAV scanner)
- VirusTotal API key (optional, only if using the VirusTotal scanner)
Sibling packages
| Package | Scope |
|---|---|
artisanpack-ui/security-full |
Meta-package — pulls in the full security suite (all six packages below) in a single require |
artisanpack-ui/security |
Core: input sanitization, output escaping, KSES, CSP, security headers |
artisanpack-ui/security-auth |
2FA, password complexity, account lockout, sessions |
artisanpack-ui/security-advanced-auth |
WebAuthn, SSO, social login, biometric, device fingerprinting |
artisanpack-ui/rbac |
Roles, permissions, hierarchy, Blade directives, Gate integration |
artisanpack-ui/security-analytics |
Event logging, anomaly detection, SIEM, dashboards |
artisanpack-ui/compliance |
GDPR / CCPA / LGPD compliance tools |
License
MIT — see LICENSE.
Contributing
Please read the contributing guidelines before opening an issue or PR.