Feb 26, 2026·5 min read·110 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')
CVE-2024-29203 identifies a cross-site scripting (XSS) vulnerability in the content ingestion and parsing mechanics of TinyMCE rich text editor. Due to a failure to enforce sandbox attributes on dynamic iframe elements and safely handle legacy embed objects, unauthenticated attackers can inject malicious elements that execute scripts within the context of the parent application session.
A technical breakdown of the OS command injection vulnerability in the shell-quote NPM package (CVE-2026-9277 / GHSA-w7jw-789q-3m8p). The bug resides in the character-by-character backslash-escaping logic applied to the .op field of object-tokens within the quote() function, which fails to match and escape line terminators due to a regex matching oversight in JavaScript. This allows unauthenticated remote attackers to execute arbitrary shell commands if they can control inputs processed by this library.
A high-severity memory corruption vulnerability exists in the V8 JavaScript engine of Google Chrome before versions 149.0.7827.102/103. The flaw arises from an incorrect bounds-check elimination during JIT compilation by the TurboFan optimizer, allowing remote attackers to achieve out-of-bounds read and write access inside the sandboxed renderer process.
An improper authentication vulnerability (CWE-287) exists in the legacy, deprecated Internet Key Exchange version 1 (IKEv1) key exchange protocol implementation in Check Point Security Gateways. The vulnerability is caused by a logic flow weakness during the certificate validation process for Remote Access VPN and Mobile Access (SSL VPN) connections. An unauthenticated remote attacker can exploit this weakness to bypass user authentication entirely, establishing a fully functional Remote Access VPN connection without a valid password.
GeoNode versions prior to 4.4.5 and 5.0.2 are vulnerable to Server-Side Request Forgery (SSRF) in the service registration endpoint. Authenticated attackers with low privileges can exploit insufficient input validation in the Web Map Service (WMS) registration module to force the application server to make outbound network queries to loopback addresses, private RFC1918 subnets, link-local scopes, and cloud metadata endpoints. This technical report details the mechanics of the vulnerability, the underlying architectural flaw, and how to effectively remediate and mitigate the associated security risks.
CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.