CVE-2026-63223 Overview
CVE-2026-63223 is an unrestricted file upload vulnerability [CWE-434] in CodeIgniter, a PHP full-stack web framework. Versions prior to 4.7.4 fail to independently enforce safe client filename extensions in the is_image and mime_in upload validation rules. A remote unauthenticated attacker can upload a file with dangerous extensions such as .php prepended with image magic bytes to bypass content-based validation. When the application preserves the client-supplied filename and stores the file in a web-accessible directory where PHP executes, the attacker achieves remote code execution. The maintainers fixed the issue in version 4.7.4.
Critical Impact
Remote attackers can achieve unauthenticated code execution on CodeIgniter applications that rely on is_image or mime_in for upload validation and store uploads under a script-enabled web root.
Affected Products
- CodeIgniter4 versions prior to 4.7.4
- Applications validating uploads via is_image without an independent extension check
- Applications validating uploads via mime_in without an independent extension check
Discovery Timeline
- 2026-07-31 - CVE-2026-63223 published to NVD
- 2026-08-01 - Last updated in NVD database
Technical Details for CVE-2026-63223
Vulnerability Analysis
The flaw resides in CodeIgniter's validation layer, specifically in the is_image and mime_in rules implemented under system/Validation/StrictRules/FileRules.php. Both rules classified an upload solely by its content-derived MIME type. An attacker could craft a polyglot file that begins with valid image magic bytes (for example, the GIF89a signature) while carrying a .php filename extension. Because validation trusted the sniffed MIME type, the framework accepted the upload as an image.
Exploitation requires three application-level conditions. First, validation must use is_image or mime_in without pairing it with ext_in. Second, the application must persist the file using the client-supplied filename rather than a generated safe name. Third, the destination directory must be web-accessible with PHP execution enabled. When all three conditions hold, the attacker requests the uploaded file over HTTP and the web server executes it as PHP.
Root Cause
The root cause is missing extension/content agreement enforcement. The is_image and mime_in rules did not verify that a non-empty client filename extension corresponded to the detected MIME type. This left a gap between what the framework considered validated and what the underlying filesystem and web server would execute.
Attack Vector
The attack vector is network-based and requires no authentication or user interaction. An attacker submits a multipart form upload containing a file with a dangerous extension and forged content-type headers or magic bytes. After upload, the attacker navigates directly to the file URL to trigger PHP execution.
// Patch excerpt: system/Validation/StrictRules/FileRules.php
use CodeIgniter\Exceptions\InvalidArgumentException;
use CodeIgniter\HTTP\CLIRequest;
+use CodeIgniter\HTTP\Files\UploadedFile;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use Config\Mimes;
Source: GitHub Commit b6e9a4f
The patched rules now reject uploads when a non-empty client filename extension is not an image extension (is_image) or does not match the detected content (mime_in). Uploads without any extension, such as JavaScript Blob uploads, remain accepted because the rules still validate file content.
Detection Methods for CVE-2026-63223
Indicators of Compromise
- Files with executable extensions such as .php, .phtml, or .phar present in upload directories that should hold only images
- Web server access logs showing GET requests to uploaded media paths returning dynamic content or unusual response sizes
- Uploaded files whose magic bytes match an image format but whose extension indicates a scripting language
- Newly created PHP files under directories such as public/uploads/ without corresponding application-generated filenames
Detection Strategies
- Inspect application validation rulesets for use of is_image or mime_in without an accompanying ext_in rule
- Scan upload storage directories for files whose extension does not match the file signature detected by file or a MIME library
- Monitor for POST requests to upload endpoints followed shortly by GET requests to the same file paths under web-accessible directories
Monitoring Recommendations
- Log every file upload including client-supplied filename, detected MIME type, and final storage path
- Alert on PHP execution originating from directories designated for user-uploaded content
- Track process creation from the web server user spawning shells or outbound network connections
How to Mitigate CVE-2026-63223
Immediate Actions Required
- Upgrade CodeIgniter4 to version 4.7.4 or later
- Audit all validation rule sets and add ext_in alongside is_image and mime_in where appropriate
- Rename uploaded files server-side using a generated safe filename rather than trusting the client-supplied name
- Configure the upload directory to disable PHP execution at the web server level
Patch Information
The fix is included in CodeIgniter4 v4.7.4. See the GitHub Release v4.7.4 and the GitHub Security Advisory GHSA-mmj4-63m4-r6h5 for details. The patch commit is b6e9a4f.
Workarounds
- Add ext_in to every validation rule that accepts uploads, pinning permitted extensions explicitly
- Store uploads outside the document root and serve them through a controller that sets a safe Content-Type
- Disable PHP handler execution in upload directories via web server configuration
- Regenerate filenames server-side using getRandomName() on the UploadedFile object before calling move()
# Apache: disable PHP execution in an uploads directory
# Place in public/uploads/.htaccess
<FilesMatch "\.(php|phtml|phar|php[0-9])$">
Require all denied
</FilesMatch>
RemoveHandler .php .phtml .phar
RemoveType .php .phtml .phar
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

