dineshuprety/laravel-zip-bomb-guard
A Laravel package that helps guard against zip bombs by validating ZIP archives before extraction, enforcing configurable size and file-count limits, and supporting safer handling of uploaded archives in your application.
Install the 2.x line:
composer require dineshuprety/laravel-zip-bomb-guard:^2.0
Note the identity move: everything now lives under the ZipBombGuard\ namespace, not DineshUprety\ZipBombGuard\. Start by grepping your app for the old prefix before running anything:
grep -rn "DineshUprety\\\\ZipBombGuard" app/ config/ routes/ database/ tests/
Read the upgrade guide first if you are coming from 1.x: docs/upgrading.md in the repo. It is short and the only genuinely dangerous change is the namespace, but the consequences are non-obvious (see Gotchas).
Look at the published config (config/zip-bomb-guard.php) before your first real use. The package's default thresholds are the thing most teams end up tuning; publishing config is unchanged from 1.x, so any existing config/zip-bomb-guard.php in your app keeps working as-is.
First use case: guard a file upload in a FormRequest.
use ZipBombGuard\Rules\NoZipBomb;
public function rules(): array
{
return [
'archive' => ['required', 'file', 'mimes:zip', new NoZipBomb],
];
}
If you only add one thing to an existing app, add this rule to the upload path that feeds any unzip step. That is the whole point of the package and it requires no other wiring.
Validation-first for user input. ZipBombGuard\Rules\NoZipBomb is the lowest-friction integration: drop it in a rules array alongside file/mimes, and the failure surfaces as a normal validation error you can localise like any other rule. Prefer this over manual checking in controllers — it keeps the rejection inside the request lifecycle and out of your domain code.
Guarded extraction in services and jobs. Put ZipBombGuard\Concerns\SafeExtractsZips on the class that actually unpacks archives (an import service, a queued processing job) rather than calling the checker ad hoc at each call site. That way any new extraction path added later inherits the guard by default, and you have exactly one place to audit.
Explicit checker injection where you need control. When you want to branch on the result instead of throwing — e.g. quarantine a suspicious upload, log it, notify an admin — inject ZipBombGuard\ArchiveSafetyChecker and decide yourself. Use constructor injection, not app('...') with a string, so the container binding key change is caught by static analysis rather than at runtime.
Queue payload hygiene is part of the upgrade. Before deploying 2.x, check jobs and failed_jobs for serialised class names containing the old prefix. Any job that referenced a package class (or a listener/rule stored as a string) will fail to unserialise after the switch, because the old names are deliberately not aliased. Safest sequence: stop workers, drain or clear pending jobs, deploy, restart workers. If you cannot drain, deploy the namespace change and a compatibility shim in the same release.
Testing. Mocks and fakes must use the new FQCN — $this->mock(\ZipBombGuard\ArchiveSafetyChecker::class). The package ships failure fixtures, so you can write assertions against genuinely malformed/oversized archives instead of hand-rolling zips. Its own suite is 41 tests / 82 assertions across a seven-job PHP/Laravel matrix including a Laravel 13 consumer, which is a reasonable signal that the discovery metadata and facade still resolve on modern Laravel.
Ops. The Artisan command and facade alias are unchanged, so existing scheduled scans and ZipBombGuard::-style facade calls keep working without edits. Config publishing and the package name are also unchanged — your composer.json constraint is the only composer-side change.
app()->make(), class_exists() checks, @var-free config arrays, database-stored class names, and serialised jobs. IDE-driven import rewrites catch the easy 80%; grep for the old prefix to catch the rest.ZipBombGuard\ArchiveSafetyChecker.^1.0 on the branch you are not migrating. Existing 1.x releases remain installable, so there's no forced deadline — but the two lines cannot coexist in one app.How can I help you explore Laravel packages today?