Laravel `files.*` Wildcard Validation Bypass via Polyglot JPEG+PHP Upload (CVE-2025-27515)
by Guaxinim (joaovicdev) · 2026-07-06
- Severity
- Critical
- CVE
- CVE-2025-27515
- Category
- web
- Affected product
- Laravel Framework (file upload validation using files.* wildcard rules)
- Affected versions
- ≤ 12.0.0 (per source repository)
- Disclosed
- 2026-07-06
- Patch status
- unpatched
Tags
References
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-06 |
| Last Updated | 2026-07-06 |
| Author / Researcher | Guaxinim (joaovicdev) |
| CVE / Advisory | CVE-2025-27515 |
| Category | web |
| Severity | Critical |
| CVSS Score | 9.8 (per NVD) |
| Status | Weaponized |
| Tags | laravel, php, file-upload, validation-bypass, polyglot, jpeg, wildcard-validation, cwe-20, rce, web-shell |
| Related | N/A |
Affected Target
| Field | Value |
|---|---|
| Software / System | Laravel Framework (file upload validation using files.* wildcard rules) |
| Versions Affected | ≤ 12.0.0 (per source repository) |
| Language / Platform | PHP / Laravel 12 web application; PoC client written in Python |
| Authentication Required | No |
| Network Access Required | Yes |
Summary
CVE-2025-27515 is a file upload validation bypass (CWE-20: Improper Input Validation) affecting Laravel applications that validate array-based file uploads with wildcard rules such as files.*. The root cause is that Laravel’s mimes: validation rule inspects file content/extension heuristics that can be satisfied simultaneously by a single polyglot file, so an attacker can craft one file that is both a technically valid JPEG and a valid PHP script. The bundled PoC ships a minimal Laravel 12 app with an /upload endpoint using exactly this files.* + mimes:jpg,png,pdf validation pattern, and a Python exploit.py client that uploads a polyglot file (JPEG magic bytes followed by an embedded PHP payload) through the multipart files[] field. If the resulting file is stored under a web-accessible path and the server can be induced to execute .php-adjacent content (e.g. via extension confusion, .htaccess misconfiguration, or a secondary LFI/inclusion vector), the payload yields remote code execution.
Vulnerability Details
Root Cause
The vulnerable controller validates uploaded files using Laravel’s wildcard array validation with only MIME/extension-based checks, and performs no content-level sanitization or re-encoding of the accepted image:
| |
Because mimes: relies on finfo/extension detection rather than strict re-encoding of image content, a file whose first bytes form a valid JPEG header (FF D8 FF E0 ...) but which also contains a trailing <?php ... ?> payload passes validation as image/jpeg, is accepted, and is written to public storage using the attacker-controlled original filename/extension — preserving the polyglot nature of the file end-to-end.
Attack Vector
- Craft a polyglot file that begins with valid JPEG magic bytes/header (
FF D8 FF E0 00 10 4A 46 49 46 ...) immediately followed by embedded PHP code, e.g.<?php system($_GET['cmd']); ?>. - Submit the file to the Laravel upload endpoint as a
files[]multipart field with a.jpgextension andimage/jpegcontent type, alongside a valid CSRF token scraped from the upload form. - The
files.*+mimes:jpg,png,pdf|max:2048validation rule passes because the file satisfies the JPEG MIME/extension checks; Laravel stores it understorage/app/public/uploads/with a timestamp-prefixed but still attacker-influenced filename. - If the storage path is web-accessible (
public/storagesymlink) and the file can be made to execute as PHP — e.g. the deployment misconfigures handler mapping, a companion LFI include pulls in the “image”, or the filename/extension is manipulated further — requesting the stored file executes the embedded PHP payload server-side.
Impact
- Arbitrary file upload leading to potential remote code execution if the uploaded polyglot is ever executed by the PHP interpreter or included by vulnerable code elsewhere in the application.
- Bypass of intended content-type/extension allow-listing (
jpg,png,pdf), undermining a common defense-in-depth control relied upon by many Laravel applications. - Stored web shell capability once execution is achieved, enabling command execution, lateral movement, and full server compromise.
Environment / Lab Setup
- PHP 8.2+ with Composer
- Laravel 12.x (bundled test app, ≤ 12.0.0 per the vulnerable range)
- SQLite/MySQL per .env.example (default Laravel scaffolding)
- Public storage symlink (`php artisan storage:link`) so uploads under storage/app/public are web-reachable
- Python 3 attacker/client tooling:
pip3 install -r requirements.txt # requests, beautifulsoup4
Proof of Concept
PoC Script
See
exploit.pyin this folder (targets the bundled Laravel app underapp/Http/Controllers/UploadController.php,routes/web.php, andresources/views/upload.blade.php).
| |
Detection & Indicators of Compromise
- Multipart POST requests to upload endpoints where the uploaded file's magic
bytes (FF D8 FF E0 / JPEG) are immediately followed by "<?php" within the
same file body.
- Files under storage/app/public/uploads (or any public upload directory)
whose content contains PHP tags despite an image extension/MIME type.
- Requests to stored "image" files with unexpected query parameters (e.g.
?cmd=) that would only matter if the file were executed as PHP.
- Laravel validation logs / application logs showing successful files.*
validation immediately preceding unusual outbound or file-system activity.
Signs of compromise:
- Unexpected
.jpg/.pngfiles in public upload directories that, when opened as text, contain<?phppayloads. - Web server access logs showing GET requests to uploaded “image” paths with
?cmd=or similar command parameters. - Unexplained child processes spawned by the PHP-FPM/web server user shortly after an upload request.
- New/unauthorized files, modified permissions, or outbound connections originating from the web server process.
Remediation
| Action | Detail |
|---|---|
| Primary fix | Upgrade Laravel past the version(s) affected by CVE-2025-27515 (per source repository, ≤ 12.0.0); consult the official Laravel advisory/release notes for the patched release once published. |
| Interim mitigation | Do not rely solely on mimes:/extension-based validation for uploaded files. Re-encode/re-process accepted images server-side (e.g. via Intervention Image/GD re-save) to strip any trailing non-image data, store uploads outside the web root or under randomized names with no direct execution mapping, disable PHP execution in upload directories (e.g. .htaccess/nginx location block denying .php execution), and validate file content structurally rather than trusting client-supplied MIME/extension alone. |
References
Notes
Mirrored from https://github.com/joaovicdev/POC-CVE-2025-27515 on 2026-07-06. The repository includes a full Laravel 12 test application (app/, routes/, resources/, database/, config/, etc.) purpose-built to demonstrate the vulnerable files.* wildcard validation pattern, plus the working exploit.py polyglot upload client described above.
| |