Weave 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

Laravel Image Sanitize Laravel Package

laravel-at/laravel-image-sanitize

Laravel middleware that re-encodes uploaded images to strip hidden malicious payloads, reducing the risk of code execution. Requires PHP 8.3+, Laravel 12/13, and Intervention Image 4.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Feature go/no-go on user-generated image uploads. Any roadmap item that accepts images — avatars, marketplace/listing photos, support-ticket attachments, CMS media library, KYC document scans — introduces an upload attack surface. This package is a concrete control you can attach to that decision, so "we're shipping uploads" becomes "we're shipping uploads with a documented mitigation" rather than an accepted silent risk.
  • Build vs. buy (vs. do nothing) for upload hardening. The alternative is hand-rolling byte-pattern detection plus an Intervention Image re-encode loop inside a custom middleware — roughly 1–3 engineer-days plus tests and ongoing ownership. This is MIT-licensed, ships as a single middleware or facade call, has CI, PHPStan level 7, Pint, and a changelog going back to v1.0.0. Buy, and spend the saved days on validation, storage hardening, and filename generation.
  • Prioritizing security hardening against feature work. Threat model is specific and severe: a valid-looking image containing embedded PHP (<?php, <?=, phar) can become remote code execution if uploads ever land in a web-executable path or are served through PHP. Severity is high, blast radius is large, and effort is small — a strong "do it now, it's cheap" candidate against competing mid-priority features.
  • Responding to a pentest/audit finding. If a security review or questionnaire flags "unrestricted file upload" or "insufficient upload content validation," this is a credible, shippable remediation item you can close with a linked PR and a config file, not a multi-quarter program.
  • Privacy/GDPR posture for image metadata. Re-encoding with strip_metadata => true removes EXIF — including GPS coordinates users often don't realize they're sharing — while auto_orientation => true keeps photos displaying correctly. That turns a privacy checkbox into a one-line config decision rather than a manual policy.
  • Defining the layered-controls story. The package positions itself as defense-in-depth, not a silver bullet: it complements, and does not replace, MIME/size validation, safe filename generation, and non-executable storage. Useful for writing the security section of a design doc so the control boundaries are explicit and no one assumes "sanitized" means "safe."
  • Scoping upload use cases by file type. Defaults cover JPEG, PNG, GIF, BMP, WebP; SVG is explicitly unsupported. That directly informs scope: SVG uploads need a separate decision (drop the feature, or add a dedicated SVG sanitizer), and PDF/video are out of scope entirely.

When to Consider This Package

Adopt when:

  • You run Laravel 12 or 13 on PHP 8.3+ and can take Intervention Image 4 as a dependency. Older stacks are possible only by pinning older majors (v3 for Intervention 3 / Laravel 12, v2.x for Laravel 9–11) and inheriting their constraints.
  • You accept raster image uploads from untrusted users and any part of the path could conceivably execute or interpret file contents — legacy upload directories, self-managed servers, multi-tenant hosting, or simply insufficient confidence in the storage configuration.
  • You want a low-ceremony control: register the middleware alias in bootstrap/app.php, apply it to upload routes, publish the config, done. No architectural change, no new service.
  • You want tunability without forking: MIME allowlist, detection patterns, driver (GD or Imagick), quality, orientation, animation decoding, and metadata stripping are all config; detection is case-insensitive, and the facade (ImageSanitize::detect() / ::sanitize()) covers non-HTTP ingestion paths like queued imports or API consumers.
  • Cost profile matters: detection is a byte scan, and re-encoding only runs on files that match a pattern. Steady-state overhead on clean uploads is low; the expensive path is the rare suspicious file.

Look elsewhere or supplement when:

  • You need SVG. Not supported by design. Use a dedicated SVG sanitizer; do not assume this covers it.
  • You need malware/AV scanning or content moderation. This is not antivirus and not an NSFW classifier. Pair with ClamAV or a scanning service if those are requirements.
  • You need PDF, Office, video, or audio ingestion safety. Out of scope; requires separate handling (and often conversion to a rendered derivative).
  • Uploads are already served exclusively from object storage/CDN with no execution path and a hardened pipeline. The marginal risk reduction is smaller — still worth a line in the risk register, but it competes with better-ROI controls.
  • You need vendor assurance artifacts. Single-maintainer, small-team project; no SOC2, no support contract. "0 dependents" on the registry is a weak adoption signal worth verifying rather than dismissing — it may be a data artifact, but plan for it: read the (small) codebase, pin the version, and be prepared to fork. MIT makes that viable.
  • You have very high-volume or very large image pipelines where a quality-100 full re-encode on flagged files could cause latency spikes. Gate it, queue it, or lower quality deliberately.
  • You need a guarantee, not a mitigation. Pattern matching is inherently bypassable — obfuscated payloads, novel encodings, and patterns absent from the list will pass. Treat this as risk reduction, and keep the storage-layer controls.

Adoption notes for the plan: the middleware handles multiple and nested file inputs (fixed in v1.3.0 and v5.0.0), which matters for real forms. Published configs do not auto-update — v5.0.1 added <?= to defaults and required teams with a published config to add it manually. Bake "diff config against package defaults" into the upgrade runbook.

How to Pitch It (Stakeholders)

For executives — one paragraph: We accept user-uploaded images, and an image is not just an image: it can carry embedded executable code that turns a routine upload feature into a server-compromise vector. This is a free, MIT-licensed, actively maintained package that scans uploads for that class of payload and re-encodes anything suspicious, stripping hidden metadata (including location data) as a side effect. The integration is a middleware registration and a config file on routes we already have — days, not a quarter — and it closes one of the highest-severity, lowest-effort items on our security backlog. It's insurance we can add this sprint, with no license cost and no architectural change. It reduces risk rather than eliminating it, so it sits alongside — not instead of — our file validation and storage controls.

For engineering — the shape of the work: Register ImageSanitizeMiddleware on upload routes via alias in bootstrap/app.php or apply it per-route. Publish image-sanitize-config and review allowed_mime_types and patterns against our actual accepted formats; keep the defaults and extend rather than replace. Note the prerequisites: PHP 8.3+, Laravel 12/13, Intervention Image 4 — if we're behind, we pin an earlier major and accept older constraints. The package resolves ImageManager from the container, so an existing binding is respected; it uses Symfony's upload MIME detection rather than mime_content_type(). Detection is case-insensitive; re-encoding only fires on matches, so clean uploads stay cheap. Constraints to design around: SVG is out of scope, we still own validation, filename generation, and non-executable storage, and published config does not track upstream — add a config diff to the dependency-upgrade checklist (v5.0.1's <?= addition is the cautionary example). Add tests covering single, multiple (images[]), and nested upload fields, plus one negative test that a flagged payload is re-encoded. Risk to log: small maintainer team, so pin versions and keep the fork option open — the codebase is small enough to own if needed.

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.
dakiquang/laravel-oauth-refresh-lock
woda/laravel-worktrees
dalefranks/ramasite
faghy/laracashbook
roundly-consulting/google-places-for-laravel
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
adachsoft/changelog-linter