Feb 26, 2026·5 min read·157 visits
Unauthenticated attackers can achieve RCE on Craft CMS by sending a malicious JSON packet to the `generate-transform` endpoint. The flaw exploits PHP's type juggling and Yii2's behavior injection logic.
A critical unauthenticated Remote Code Execution (RCE) vulnerability in Craft CMS that arises from improper input validation in the asset transformation engine. By injecting an array into the `handle` parameter, attackers can manipulate Yii2 framework behaviors to instantiate arbitrary PHP objects, leading to a full system compromise. This vulnerability bypasses previous fixes for CVE-2023-41892 and is actively exploited in the wild.
In the world of web application security, the most dangerous assumptions are often the simplest ones. In Craft CMS, the assumption was that a request parameter named handle would always be a string—a filename, a slug, a simple identifier. But this is PHP, a language that happily treats everything as a suggestion rather than a rule.
CVE-2025-32432 is what happens when you trust user input to define the structure of your objects. It lives in the actionGenerateTransform method of the AssetsController. This endpoint is designed to generate image thumbnails on the fly. It's publicly accessible because, logically, you want your website visitors to see images without logging in.
However, this endpoint takes the handle parameter and passes it straight into the deep magic of the Yii2 framework (on which Craft is built). If an attacker decides that handle isn't a string like "thumbnail", but rather a complex associative array, the application doesn't complain. It attempts to parse it. This is where the door to the kingdom is left unlocked.
To understand this exploit, you have to understand the specific flavor of "magic" used by Yii2. The framework has a concept called Behaviors. Think of them as dynamic mixins—ways to attach methods and properties to a class at runtime.
When Craft CMS processes the handle, it eventually calls App::configure($object, $properties). This function iterates through the input array. If it sees a key that starts with as , it treats it as a request to attach a Behavior. For example, "as behaviorName": { ... }.
> [!NOTE] > This is a classic "Object Injection via Configuration" pattern. The application blindly trusts the configuration array provided by the user.
The vulnerability is a logic flaw in how Yii2 validates these behaviors. It checks if the configuration array contains a class key that implements the Behavior interface. That sounds safe, right?
Wrong.
The framework's object factory (Yii::createObject) has a quirk: if you provide both a class key AND a __class key, it uses class for validation checks but uses __class for the actual object instantiation. This allows an attacker to pass the validation check with a harmless class, while simultaneously instantiating a malicious gadget class using __class.
So how do we turn "I can create an object" into "I own your server"? We need a Gadget Chain. The researchers (and the attackers known as "Mimo") found two distinct paths.
Path A: The One-Shot (PHP Info)
This method uses the GuzzleHttp\Psr7\FnStream class. This class has a destructor (__destruct) that calls a function defined in the _fn_close property.
By injecting an array defining a behavior with __class set to FnStream and _fn_close set to phpinfo, the attacker triggers the function the moment the request ends and the object is destroyed.
Path B: The Heavy Hitter (Full RCE) This is where it gets cynical. To execute arbitrary commands, attackers use a two-step process involving Local File Inclusion (LFI).
/admin/dashboard?x=<?php system($_GET['cmd']); ?>. Craft CMS forces a login redirect but logs the "return URL" (containing the PHP payload) into a session file on the disk (e.g., /var/lib/php/sessions/sess_...).generate-transform. They instantiate yii\rbac\PhpManager. This class has an init() method (called automatically) that includes a file specified by the itemFile property. The attacker sets itemFile to the path of the dirty session file.Boom. The session file is included, the PHP code inside it executes, and the server runs the command.
The fix for this critical vulnerability is embarrassingly simple. It highlights just how fragile loose typing can be.
The patch (Commit e1c85441fa47eeb7c688c2053f25419bc0547b47) simply enforces that the input is actually a string before letting it anywhere near the image transformation logic.
// src/controllers/AssetsController.php
public function actionGenerateTransform(): Response
{
$assetId = $this->request->getRequiredBodyParam('assetId');
$handle = $this->request->getRequiredBodyParam('handle');
// THE FIX: explicitly check the type
if (!is_string($handle)) {
throw new BadRequestHttpException('Invalid transform handle.');
}
// ... existing logic ...
$transform = ImageTransforms::normalizeTransform($handle);
}Before this if statement existed, $handle could be anything. After this patch, the exploit chain is dead on arrival because the array injection is rejected immediately. It is a stark reminder: Always validate your input types, not just their existence.
This isn't just a theoretical bug. It is being actively exploited by groups like "Mimo" to deploy malware and ransomware. Because the endpoint is unauthenticated, every single exposed Craft CMS install within the affected version range is vulnerable.
The attacker doesn't need to guess passwords or brute force login forms. They just need to send one POST request. The EPSS score is in the 99th percentile for a reason. If you run Craft CMS 3, 4, or 5 and haven't updated since April 2025, assume you are compromised.
Furthermore, this was an "incomplete fix" scenario (fixing CVE-2023-41892). This means threat actors were already looking at this code, knew it was fragile, and likely found this bypass long before the defenders did.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Craft CMS Pixel & Tonic | 3.0.0-RC1 - 3.9.14 | 3.9.15 |
Craft CMS Pixel & Tonic | 4.0.0-RC1 - 4.14.14 | 4.14.15 |
Craft CMS Pixel & Tonic | 5.0.0-RC1 - 5.6.16 | 5.6.17 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-94 (Code Injection) |
| CVSS Score | 10.0 (Critical) |
| Attack Vector | Network (Unauthenticated) |
| EPSS Score | 0.8036 (99.09%) |
| Exploit Status | Active / Weaponized |
| Impact | Remote Code Execution (RCE) |
Improper Control of Generation of Code ('Code Injection')
A heap-based buffer overflow vulnerability (CVE-2026-71328) exists within the parser component of Microsoft Visual Studio and Microsoft .NET runtimes. This vulnerability permits an unauthenticated remote attacker to execute arbitrary code with the privileges of the running application, provided they can convince a user to load a maliciously crafted project file, solution, or stream.
CVE-2026-69439 is a high-severity elevation of privilege vulnerability in Microsoft .NET and Visual Studio, originating from a heap-based buffer overflow (CWE-122) within native parsing libraries. An unauthenticated attacker can achieve code execution under the privileges of the active process by convincing a user to open a specially crafted project, metadata stream, or dependency.
Prior to version 1.7.1, smol-toml is vulnerable to an infinite loop Denial of Service when parsing a malformed TOML payload containing an unclosed comment inside an array or inline table.
CVE-2026-69522 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET runtimes, .NET Framework, and Visual Studio caused by a heap-based buffer overflow (CWE-122). An unauthenticated attacker can exploit this flaw by inducing a user to open a malicious project file or by transmitting crafted payloads over the network, leading to arbitrary code execution within the context of the running application.
An Improper Handling of Highly Compressed Data (Data Amplification) vulnerability (CVE-2026-69304) exists in Microsoft ASP.NET Core and Microsoft .NET. It allows unauthenticated remote attackers to trigger resource exhaustion and denial of service via highly compressed request payloads.
A critical remote code execution vulnerability exists in the Composer PHP dependency manager due to improper neutralization of command parameters passed to the Perforce CLI client. Unauthenticated attackers can exploit this flaw via crafted package metadata in custom repositories or lock files, triggering arbitrary OS command execution when a user or automated CI/CD pipeline runs Composer commands.