CVE-2026-63223
PHP vulnerability analysis and mitigation

Overview

CVE-2026-63223 is a critical unsafe file upload validation bypass vulnerability in CodeIgniter 4 (the codeigniter4/framework Composer package) that can lead to remote code execution. The is_image and mime_in upload validation rules failed to independently enforce safe client filename extensions, allowing attackers to upload PHP webshells disguised with image magic bytes. All versions prior to 4.7.4 are affected. The vulnerability was published on July 7, 2026 by maintainer paulbalandan and carries a CVSS v3.1 base score of 9.8 (Critical) (Github Advisory, CodeIgniter Advisory).

Technical details

The root cause (CWE-434: Unrestricted Upload of File with Dangerous Type) lies in how the is_image and mime_in validation rules in system/Validation/StrictRules/FileRules.php evaluated uploads solely by content-derived MIME type, without checking the client-supplied filename extension. An attacker could prepend valid image magic bytes (e.g., GIF89a, JPEG, or PNG headers) to a PHP webshell, causing the MIME detection to classify the file as an image while the filename retains a .php extension. The fix in v4.7.4 adds hasInvalidImageClientExtension() and hasMismatchedClientExtension() helper methods that reject uploads where the client filename extension does not correspond to an image type or does not match the detected file content (CodeIgniter Advisory, Patch Commit). Exploitation requires three concurrent application conditions: using is_image or mime_in without an independent extension check, preserving the client-supplied filename on disk, and storing uploads in a web-accessible directory where PHP execution is enabled.

Impact

Successful exploitation grants an unauthenticated remote attacker arbitrary code execution on the server with the privileges of the web application process. This results in full compromise of confidentiality (access to application data, credentials, environment variables), integrity (ability to modify files, inject backdoors, alter database content), and availability (potential for service disruption or ransomware deployment). The attacker can use the foothold for lateral movement within the hosting environment, data exfiltration, or persistent access via additional webshells (Github Advisory, CodeIgniter Advisory).

Exploitability

A public proof-of-concept exploit is available on GitHub at imbas007/CVE-2026-63223-POC, consisting of a Python exploit script (exploit/exploit.py) with interactive shell capability, a Docker-based vulnerable lab environment, and multiple documented attack vectors using GIF89a, JPEG, and PNG magic bytes prepended to PHP webshells (PoC Repository). A second PoC repository (shinthink/CVE-2026-63223) has also appeared. The EPSS score is approximately 0.49%, and as of the time of reporting there is no confirmed evidence of in-the-wild exploitation; the NVD SSVC assessment marks exploitation as "none" but notes the vulnerability is automatable with total technical impact (Github Advisory). The vulnerability is not currently listed in the CISA KEV catalog, though CISA referenced it in a vulnerability bulletin (SB26-215).

Exploitation steps

  1. Reconnaissance: Identify CodeIgniter 4 applications (versions < 4.7.4) with file upload functionality using tools like Shodan, Censys, or manual browsing. Look for upload forms that accept images (profile pictures, attachments, etc.).
  2. Craft malicious payload: Create a PHP webshell file named evil.php and prepend valid image magic bytes to bypass MIME detection. For example, prepend GIF89a to <?php system($_GET['c']); ?> to produce a file that reads as a GIF but executes as PHP.
  3. Upload the file: Submit the crafted file via the application's upload endpoint. The is_image or mime_in validation rule will pass because the content MIME type resolves to image/gif, while the .php extension is not checked.
  4. Locate the uploaded file: Determine the web-accessible upload directory (commonly /uploads/, /public/uploads/, or similar). The application preserves the client-supplied filename evil.php.
  5. Execute arbitrary commands: Send an HTTP request to the uploaded file, e.g., curl http://target/uploads/evil.php?c=id. The web server executes the PHP script, returning command output.
  6. Establish persistent access: Use the --shell flag of the PoC exploit script for an interactive reverse shell, or upload additional backdoors for persistence (PoC Repository, CodeIgniter Advisory).

Indicators of compromise

  • Network: HTTP POST requests to upload endpoints containing files with image MIME types (image/gif, image/jpeg, image/png) but .php, .phtml, .phar, or other executable extensions in the filename; outbound connections from the web server process to attacker-controlled IPs following an upload event.
  • File System: Presence of .php (or .phtml, .phar) files in web-accessible upload directories (e.g., /public/uploads/, /uploads/); files with image magic bytes (GIF89a, \xFF\xD8\xFF, \x89PNG) at the start of PHP script files; unexpected modification timestamps in upload directories.
  • Logs: Web server access logs showing POST requests to upload endpoints followed shortly by GET requests to the same directory for .php files; requests to uploaded files with query parameters like ?c=, ?cmd=, or ?exec=; PHP error logs showing execution of shell commands.
  • Process: Unusual child processes spawned by the web server or PHP-FPM process (e.g., sh, bash, curl, wget, python, nc); unexpected outbound network connections from the web server process (PoC Repository, CodeIgniter Advisory).

Mitigation and workarounds

Upgrade CodeIgniter 4 to version 4.7.4 or later, which adds extension validation to the is_image and mime_in rules (CI4 Release). If immediate upgrade is not possible, apply the following workarounds: (1) store uploaded files outside the public web root (e.g., writable/uploads/); (2) use $file->store() or $file->move($path, $file->getRandomName()) instead of preserving the client-supplied filename; (3) disable PHP script execution in any public upload directory via web server configuration (Apache php_flag engine off or Nginx location rules); (4) add an independent ext_in validation rule alongside is_image or mime_in to explicitly allowlist safe extensions (Github Advisory).

Community reactions

The vulnerability received coverage on security news sites including SecurityOnline.info and TheHackerWire, and was discussed on social platforms including Mastodon and LinkedIn shortly after disclosure (Feedly). CISA included it in vulnerability bulletin SB26-215. Community reaction on Reddit's r/pwnhub noted the availability of a working PoC. The CodeIgniter maintainer community responded positively to the v4.7.4 release, with 20 community members reacting to the release on GitHub (CI4 Release).

Additional resources


SourceThis report was generated using AI

Related PHP vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-59989CRITICAL9.2
  • PHP logoPHP
  • phalcon/cphalcon
NoYesAug 21, 2026
CVE-2026-63135HIGH8.2
  • PHP logoPHP
  • yourls/yourls
NoYesAug 21, 2026
GHSA-p2ch-c2c3-4xm5MEDIUM6.1
  • PHP logoPHP
  • winter/wn-backend-module
NoYesAug 20, 2026
GHSA-8hgv-xc77-jmcrMEDIUM5.1
  • PHP logoPHP
  • getgrav/grav
NoYesAug 21, 2026
GHSA-hq84-x37p-j6q5MEDIUM4.5
  • PHP logoPHP
  • winter/wn-backend-module
NoYesAug 20, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management