🕵️ SicherheitslückenSQLi & XSS Vulnerabilities in a Popular Airlines Website!(10.10.2017 um 20:34 Uhr)
🕵️ SicherheitslückenBugcrowd’s Domain & Subdomain Takeover vulnerability!(10.10.2017 um 21:20 Uhr)
🕵️ SicherheitslückenUnrestricted File Upload to RCE | Bug Bounty POC(19.12.2017 um 13:48 Uhr)
🕵️ SicherheitslückenHow I was able to Bypass XSS Protection on HackerOne's Private Program(02.02.2018 um 13:10 Uhr)
🕵️ SicherheitslückenIOS 11.4 Siri Auth Bypass | CVE-2018-4238(22.05.2018 um 15:31 Uhr)
🪟 Windows TippsHow to Enable Windows 11 Screen Savers(07.09.2026 um 12:41 Uhr)
🪟 Windows TippsMicrosoft Phone Link Not Showing Messages on Windows 11? Fix It(09.09.2026 um 07:52 Uhr)
🕵️ SicherheitslückenSQLi & XSS Vulnerabilities in a Popular Airlines Website!(10.10.2017 um 20:34 Uhr)
🕵️ SicherheitslückenBugcrowd’s Domain & Subdomain Takeover vulnerability!(10.10.2017 um 21:20 Uhr)
🕵️ SicherheitslückenUnrestricted File Upload to RCE | Bug Bounty POC(19.12.2017 um 13:48 Uhr)
🕵️ SicherheitslückenHow I was able to Bypass XSS Protection on HackerOne's Private Program(02.02.2018 um 13:10 Uhr)
🕵️ SicherheitslückenIOS 11.4 Siri Auth Bypass | CVE-2018-4238(22.05.2018 um 15:31 Uhr)
🪟 Windows TippsHow to Enable Windows 11 Screen Savers(07.09.2026 um 12:41 Uhr)
🪟 Windows TippsMicrosoft Phone Link Not Showing Messages on Windows 11? Fix It(09.09.2026 um 07:52 Uhr)

🔧 Programmierung 🕛 vor 2 Monaten 6 Min Lesezeit
0

Sanitizing Image Uploads in Laravel: Stopping PHP Payload Injection via Image Files

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




TL;DR



Image uploads aren't just images. A JPEG can carry a PHP web shell in its EXIF comment and still pass MIME checks, extension checks, and even getimagesize(). If that file ever lands somewhere executable - a misconfigured public/uploads, a .htaccess override, a chained LFI - you've got remote code execution.



laravel-at/laravel-image-sanitize is a small middleware that scans uploaded images for payload markers (<?php, phar) and re-encodes anything suspicious through Intervention Image, stripping the payload before your controller ever sees the file.




CODE
composer require laravel-at/laravel-image-sanitize






It's defense-in-depth, not a replacement for validation. Here's why you need it anyway, and how it works.






The problem: images that aren't just images



A valid image file is just bytes with a known header. Nothing stops you from appending arbitrary text after that header. The image still renders fine in a browser - image decoders ignore trailing garbage.



This is the classic "GIFAR" / polyglot trick, still alive in 2026:




CODE
exiftool -Comment='<?php system($_GET["c"]); ?>' shell.jpg






That file:




  • Has a real JPEG header. file shell.jpg says JPEG image data.


  • Passes getimagesize(). PHP reads the header, never the comment.


  • Passes $request->file('avatar')->isValid() and 'image' validation rules.


  • Renders normally in <img> tags.


  • Contains a working PHP payload in its EXIF data.




If an attacker can get this file written with a .php extension somewhere reachable - via a separate path traversal bug, a misconfigured rename, or a server that executes .jpg.php - they get code execution. Plenty of real-world breaches chain exactly this: an "unrelated" upload bug plus a permissive storage path.






Why MIME and extension checks aren't enough



Laravel's standard validation:




CODE
$request->validate([
'avatar' => 'required|image|mimes:jpg,png,gif|max:2048',
]);






This checks the container, not the contents. mimes: looks at the file extension and a magic-byte sniff. image confirms it decodes as an image. None of that inspects what else is sitting inside the file alongside valid image data.



MIME sniffing answers "is this technically an image?" It doesn't answer "is this image free of embedded code?" Those are different questions, and most upload pipelines only ask the first one.






The fix: detect and re-encode



laravel-image-sanitize adds a layer that asks the second question. The flow is four steps:




  1. Filter by MIME type. The middleware only inspects files matching your allow-list (JPEG, PNG, GIF, BMP, WebP by default).


  2. Scan for payload markers. File contents are checked against configured patterns - <?php and phar out of the box.


  3. Re-encode on match. If a marker is found, the image is decoded and re-encoded from scratch through Intervention Image. Decoding only reads pixel data; anything appended outside the actual image stream gets dropped on re-encode.


  4. Replace before the controller runs. The rewritten bytes replace the original upload content. Your controller, your validation rules, your storage logic - none of it changes.




The key insight: a genuine image decoder never reads the EXIF comment as executable. Re-encoding rebuilds the file from pixel data only, so anything appended after the image stream - your PHP payload - never makes it into the output file.






Middleware usage



Attach it directly to upload routes:




CODE
use App\Http\Controllers\FileController;
use LaravelAt\ImageSanitize\ImageSanitizeMiddleware;

Route::post('/files', [FileController::class, 'upload'])
->name('file.upload')
->middleware(ImageSanitizeMiddleware::class);






Or register a readable alias in bootstrap/app.php (Laravel 12/13):




CODE
use Illuminate\Foundation\Configuration\Middleware;
use LaravelAt\ImageSanitize\ImageSanitizeMiddleware;

->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'image-sanitize' => ImageSanitizeMiddleware::class,
]);
})









CODE
Route::post('/files', [FileController::class, 'upload'])
->name('file.upload')
->middleware('image-sanitize');









Direct usage outside the middleware



Handling raw image bytes in a job, an API client, or a CLI import? Call the sanitizer directly:




CODE
if (ImageSanitize::detect($contents)) {
$contents = (string) ImageSanitize::sanitize($contents);
}






detect() runs the pattern scan; sanitize() does the decode/re-encode pass. Useful for queued processing where the file never goes through an HTTP route.






Configuration



Publish the config when you need to change defaults:




CODE
php artisan vendor:publish --tag=image-sanitize-config






Defaults:




CODE
return [
'allowed_mime_types' => [
'image/jpeg',
'image/png',
'image/gif',
'image/bmp',
'image/webp',
],

'patterns' => [
'<?php',
'
phar',
],

'
driver' => \Intervention\Image\Drivers\Gd\Driver::class,
'
quality' => 100,
'
auto_orientation' => true,
'
decode_animation' => true,
'
strip_metadata' => true,
];






A few notes:




  • quality => 100 means JPEG re-encoding is near-lossless by default - bump it down if you also want smaller files.


  • strip_metadata => true removes EXIF data on re-encode, which is also a privacy win (no leaked GPS coordinates from phone uploads).


  • decode_animation => true handles animated GIF/WebP correctly instead of flattening to one frame.


  • SVG is not in the allow-list. SVG can carry active content (<script>, event handlers) and needs a different threat model than raster re-encoding solves. Don't add it without your own sanitization for that format.







What this doesn't do



Be clear-eyed about scope. This package:




  • Doesn't replace mimes:/image validation rules - keep them.


  • Doesn't do authorization, rate limiting, or virus scanning.


  • Doesn't make storing uploads inside a public, executable path safe. Keep uploaded files out of public/ execution paths regardless.


  • Doesn't cover SVG, PDF, or non-image uploads.




It's one layer that closes a specific gap: code smuggled inside otherwise-valid image bytes. Stack it with proper storage isolation (uploads on non-executable disks, served via signed URLs or a controller, not direct web-root access) and you've meaningfully reduced the blast radius of a polyglot file slipping through.



Requirements: Laravel ^12.0 | ^13.0, PHP ^8.3, MIT licensed.






FAQ



Does this replace Laravel's image validation rule? No. Run both. Validation confirms the file is a structurally valid image; the sanitizer checks for embedded payload markers and re-encodes when found. They cover different failure modes.



Will re-encoding degrade my images? Quality defaults to 100, so JPEG loss is minimal. PNG/GIF/WebP re-encoding via GD is lossless for typical use. If you need smaller output, lower quality in the config.



Why isn't SVG supported? SVG is XML and can contain <script> tags or event handlers that execute in some rendering contexts. Re-encoding a raster image doesn't translate to "sanitizing" markup - SVG needs its own sanitizer (e.g., stripping script/event-handler nodes), which is out of scope here.



Does this stop every upload-based attack? No single package does. This closes the "PHP/PHAR embedded in image bytes" gap specifically. Combine it with storage isolation, strict MIME/extension validation, and not executing PHP from upload directories.






Join the discussion




  • What's the worst upload-based exploit you've seen chained with a storage misconfig?


  • quality => 100 by default - smart, or should it optimize for file size out of the box? Disagree below.


  • Hit a case where you needed SVG sanitization? What blocked you from shipping it?







Sources





Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
2 Quellen
Bugcrowd’s Domain & Subdomain Takeover vulnerability!
1 Quelle
SQLi & XSS Vulnerabilities in a Popular Airlines Website!
1 Quelle
Unrestricted File Upload to RCE | Bug Bounty POC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Sanitizing Image Uploads in Laravel: Stopping PHP Payload Injection via Image Files

Thematisch verwandte Begriffe: Sanitizing, Image, Uploads, Laravel · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...