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

CVE-2026-48062: CodeIgniter Upload Validation RCE Flaw

CVE-2026-48062 is a remote code execution vulnerability in CodeIgniter's file upload validation that allows attackers to bypass extension checks. This article covers technical details, affected versions, and mitigations.

Published:

CVE-2026-48062 Overview

CVE-2026-48062 is a file upload validation bypass in CodeIgniter, a PHP full-stack web framework. Versions prior to 4.7.3 contain a flaw in the ext_in validation rule located in system/Validation/StrictRules/FileRules.php. The rule checks the MIME-derived guessed extension rather than the client-provided filename extension. Attackers can upload a file named shell.php containing GIF-like content and pass validation rules such as uploaded[avatar]|is_image[avatar]|mime_in[avatar,image/gif]|ext_in[avatar,gif]. When applications save the file using the original client filename in a web-accessible directory that executes PHP, this enables arbitrary code execution. The issue is fixed in version 4.7.3.

Critical Impact

Unauthenticated remote attackers can upload PHP webshells disguised as images, resulting in arbitrary code execution on affected CodeIgniter applications [CWE-434].

Affected Products

  • CodeIgniter4 versions prior to 4.7.3
  • Applications using the ext_in validation rule for user-controlled uploads
  • Applications saving uploads with $file->move($path) using original client filenames in web-accessible directories

Discovery Timeline

  • 2026-07-17 - CVE-2026-48062 published to NVD
  • 2026-07-23 - Last updated in NVD database

Technical Details for CVE-2026-48062

Vulnerability Analysis

The vulnerability resides in the ext_in validation rule implementation within system/Validation/StrictRules/FileRules.php. The rule was designed to restrict uploads to specific file extensions but incorrectly evaluated the extension inferred from MIME content sniffing instead of the actual client-supplied filename extension.

An attacker crafts a polyglot file that begins with valid GIF magic bytes but contains PHP code and names it shell.php. CodeIgniter's MIME detection maps the content to image/gif and returns gif as the guessed extension. The ext_in[avatar,gif] rule then compares gif against the allow-list and returns success, despite the filename ending in .php.

When the application persists the file with $file->move($path) using the original filename in a directory served by the web server with PHP execution enabled, requesting the uploaded file triggers PHP interpretation of the embedded payload.

Root Cause

The rule dereferenced $file->guessExtension() instead of $file->getClientExtension(). This creates a Type Confusion between content-derived and filename-derived extension metadata, allowing the client-controlled filename extension to remain unvalidated [CWE-434].

Attack Vector

Exploitation requires a network-accessible upload endpoint, a validator chain that relies on ext_in, storage under the web root using client filenames, and PHP execution enabled in the upload directory. No authentication or user interaction is required in the vulnerable code path.

php
// Security patch applied to system/Validation/StrictRules/FileRules.php
// Before (vulnerable):
//     if (! in_array($file->guessExtension(), $params, true)) {
//         return false;
//     }

// After (fixed):
// Check the real filename extension, not only the guessed extension.
$clientExtension = strtolower($file->getClientExtension());

if ($clientExtension === '' || ! in_array($clientExtension, $params, true)) {
    return false;
}

if ($file->guessExtension() !== $clientExtension) {
    return false;
}

Source: GitHub Commit 29299349

Detection Methods for CVE-2026-48062

Indicators of Compromise

  • Uploaded files with double extensions or executable suffixes (.php, .phtml, .phar) inside directories that previously held only image content
  • Files whose declared MIME type does not match the filename extension present on disk
  • Web server access logs showing GET or POST requests to newly created files in upload directories
  • Outbound network connections originating from the PHP-FPM or web server process shortly after an upload event

Detection Strategies

  • Inspect application logs for validation chains containing ext_in combined with mime_in on user upload endpoints
  • Scan web-accessible upload directories for files whose content signature disagrees with their filename extension
  • Deploy web application firewall rules that block multipart uploads containing PHP tags (<?php, <?=) in the file body
  • Monitor process creation from web server users spawning shells, curl, wget, or scripting interpreters

Monitoring Recommendations

  • Alert on file creation events in web-writable directories where the file extension matches a server-executable type
  • Correlate HTTP POST requests to upload handlers with subsequent GET requests to the same filename
  • Track CodeIgniter application versions across the fleet and flag any instance below 4.7.3

How to Mitigate CVE-2026-48062

Immediate Actions Required

  • Upgrade CodeIgniter4 to version 4.7.3 or later, which validates both the client filename extension and MIME-derived extension
  • Audit application code for calls to $file->move($path) that reuse the original client filename and replace them with server-generated names
  • Remove PHP execution permissions from directories that store user uploads
  • Review existing upload directories for polyglot files created before the patch was applied

Patch Information

The fix is included in CodeIgniter4 v4.7.3. The patch modifies system/Validation/StrictRules/FileRules.php to call getClientExtension(), verify it against the allow-list, and require it to match guessExtension(). Refer to GitHub Release v4.7.3 and GitHub Security Advisory GHSA-2gr4-ppc7-7mhx.

Workarounds

  • Replace ext_in reliance with server-side allow-listing of a randomly generated filename plus a fixed safe extension
  • Store uploads outside the web root and serve them through a controller that sets a non-executable Content-Type
  • Configure the web server to disable PHP handlers within upload directories
  • Add an explicit filename extension check before calling $file->move()
bash
# Apache configuration example: disable PHP execution in the uploads directory
<Directory "/var/www/app/public/uploads">
    php_admin_flag engine off
    <FilesMatch "\.(php|phtml|phar|phps)$">
        Require all denied
    </FilesMatch>
</Directory>

# Composer upgrade command
composer require codeigniter4/framework:^4.7.3

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.