Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-63223

CVE-2026-63223: CodeIgniter File Upload RCE Vulnerability

CVE-2026-63223 is a remote code execution flaw in CodeIgniter PHP framework that allows attackers to upload malicious files via unsafe validation rules. This article covers technical details, affected versions, and patches.

Published:

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.

php
// 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()
bash
# 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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.