Download the PHP package abdian/laravel-upload-guard without Composer
On this page you can find all versions of the php package abdian/laravel-upload-guard. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download abdian/laravel-upload-guard
More information about abdian/laravel-upload-guard
Files in abdian/laravel-upload-guard
Package laravel-upload-guard
Short Description Secure file upload validation for Laravel β fail-closed scanning for polyglot web shells, malicious PDFs/SVGs, zip bombs, Office macros, and spoofed MIME types.
License MIT
Homepage https://github.com/abdian/laravel-upload-guard
Informations about the package laravel-upload-guard
Why?
Laravel's built-in mimes / mimetypes rules trust the client-declared type
and a coarse extension map. An attacker can upload shell.php renamed to
avatar.jpg, a real JPEG with PHP appended after the image data (a polyglot
web shell), an SVG carrying <script>, a PDF with an auto-run /JavaScript
action, or a 42 KB zip that expands to petabytes. None of those are caught by
extension checks.
Upload Guard inspects the actual bytes β magic structure, decoded PDF/zip streams, sanitized SVG/Office internals β and blocks anything it cannot prove is safe.
π Design principle: fail closed
When the package cannot be sure a file is safe, it blocks the upload. Unknown content types, unparsable containers, and scanner exceptions all resolve to reject β never to allow. Stricter than lax validators by design. It raises the bar a lot, but content scanning is best-effort β pair it with the operational hardening steps below.
Threat coverage
| Threat | How Upload Guard handles it |
|---|---|
| π Polyglot web shells (PHP in JPEG / PDF / ZIP) | Always-on code scan on every upload, regardless of detected type |
| π Spoofed MIME / double extension | Structural byte detection + strict extension β content matching |
| πΌοΈ Malicious SVG (XSS / XXE) | Allowlist sanitization; DOCTYPE/entity/script stripping; stored clean |
π Malicious PDF (/JavaScript, /OpenAction, /Launch) |
Decode-before-scan, indirect-/Filter resolution, bounded inflation |
| π£ Zip bombs & zip-slip | Global actual-bytes cap across nested archives; traversal / symlink / NTFS-ADS rejection |
| π Office macros + macro-less RCE | OOXML and legacy OLE/CFB; VBA, ActiveX, DDE/DDEAUTO, remote attachedTemplate |
| 𧨠Image decompression bombs | Header pixel/byte cap before any decode; optional re-encode to strip payloads |
| π Upload DoS | Hard size caps + optional per-IP rate limiting + opt-in forensic quarantine |
Table of contents
- Installation
- Quick start
- Usage
- mimes rule
- Fluent configuration
- Individual rules
- Fluent API reference
- Configuration
- How it works
- Limitations & not a security boundary
- Testing
- Security
- License
Installation
The service provider is auto-discovered. Publish the (fully commented) config to tune behavior:
Requirements
| PHP | 8.1 Β· 8.2 Β· 8.3 Β· 8.4 Β· 8.5 |
| Laravel | 10 Β· 11 Β· 12 Β· 13 |
| Required extensions | fileinfo, zip, dom, libxml |
| Optional extensions | exif (EXIF inspection/stripping) Β· gd or imagick (image re-encode mode) |
Optional extensions degrade gracefully β the package installs and runs without them.
Quick start
The single safeguard rule runs β by default, no fluent calls required:
β structural MIME detection + dangerous-type blocking Β· β strict extension/content matching Β· β always-on code scanning Β· β SVG sanitization Β· β image & PDF scanning Β· β archive and Office-macro scanning.
Usage
With Laravel's mimes rule
safeguard reads the allowed extensions and enforces that the file's real
content type matches them.
Fluent configuration
Individual rules
Compose only the scanners you need:
| Rule | Description |
|---|---|
safeguard |
All-in-one, fail-closed pipeline |
safeguard_mime:type1,type2 |
Real content-type allowlist (+ dangerous-type block) |
safeguard_php |
Always-on PHP/script code scan |
safeguard_svg |
Allowlist SVG sanitization |
safeguard_image |
Image bomb / metadata / byte / trailing-data scan |
safeguard_pdf |
Decode-before-scan PDF analysis |
safeguard_archive |
Streaming archive inspection (zip/tar/gz) |
safeguard_office |
OOXML + legacy OLE macro / DDE / template detection |
safeguard_dimensions:maxW,maxH,minW,minH |
Image dimension limits |
safeguard_pages:min,max |
PDF page-count limits |
Note on
safeguard_archivestring params: parameters are added to the block list (e.g.safeguard_archive:iso,binalso blocks.iso/.bin). To allow an otherwise-blocked extension, use the fluent rule:(new SafeguardArchive)->allow(['sh']).
Fluent API reference
All methods on Abdian\UploadGuard\Rules\Safeguard return $this (chainable).
| Method | Effect |
|---|---|
allowedMimes(array $mimes) |
Restrict to a real-content-type allowlist ('image/*' wildcards supported) |
imagesOnly() / pdfsOnly() / documentsOnly() / archivesOnly() |
Restrict to a file family |
maxDimensions(int $w, int $h) / minDimensions(int $w, int $h) |
Image dimension bounds |
dimensions(int $minW, int $minH, int $maxW, int $maxH) |
All four bounds at once |
maxPages(int) / minPages(int) / pages(int $min, int $max) |
PDF page-count bounds |
blockGps() |
Reject images that contain GPS/EXIF location data |
stripMetadata() |
Strip metadata from images |
blockJavaScript() |
Reject PDFs containing JavaScript |
blockExternalLinks() |
Reject PDFs containing external links |
strictExtensionMatching(bool = true) |
Force/disable extension β content matching |
scanArchives(bool = true) |
Toggle archive scanning (on by default) |
blockMacros(bool = true) / allowMacros() |
Toggle Office-macro blocking (on by default) |
Configuration
The published config/safeguard.php is fully commented; highlights:
Every key is also overridable via environment variables (e.g.
SAFEGUARD_ARCHIVE_SCAN, SAFEGUARD_SVG_MODE, SAFEGUARD_IMAGE_REENCODE).