Craft CMS RCE: When 'Magic' Methods Cast a Dark Spell
Jan 5, 2026·6 min read
Executive Summary (TL;DR)
Researchers found a way to bypass previous RCE protections in Craft CMS by abusing a built-in Yii2 behavior (`AttributeTypecastBehavior`). Authenticated administrators can inject a malicious configuration array that maps system commands (like `system` or `exec`) to component attributes. When the component saves or renders, the command triggers. The fix involves recursively stripping `as` and `on` keys from configuration arrays.
An authenticated Remote Code Execution (RCE) vulnerability in Craft CMS exploits the underlying Yii2 framework's dynamic component configuration. By leveraging the 'as' and 'on' magic keys in JSON payloads, attackers can attach malicious behaviors to internal components, bypassing previous security filters to execute arbitrary system commands.
The Hook: The Dark Art of Dynamic Configuration
In the world of PHP frameworks, "magic" is a double-edged sword. It makes developers' lives easier by automating tedious tasks, but it often leaves a backdoor unlockable by design. Craft CMS is built on top of the Yii2 framework, a robust beast that heavily utilizes the Service Locator pattern and dynamic component configuration. In Yii2, almost everything is a component, and components are often initialized using massive configuration arrays. This is where our story begins.
The vulnerability lies in how Yii2 handles these configuration arrays. The framework looks for two specific keys that act as magic incantations: as <behaviorName> and on <eventName>. The former allows you to dynamically attach a "Behavior" class to an object, modifying its capabilities at runtime. The latter allows you to bind an event listener. It’s a powerful feature for modularity—imagine equipping a character in an RPG with a new weapon (as Sword) that triggers an effect when they attack (on Attack).
However, when user input flows directly into these configuration arrays, the RPG becomes a horror game. If an attacker can control the array passed to Yii::createObject() or Yii::configure(), they aren't just passing data; they are architecting the application's logic in real-time. Craft CMS had previously attempted to lock this down by restricting which classes could be instantiated, but CVE-2025-68455 proves that sometimes the weapon you need is already inside the house.
The Flaw: A Gadget Hidden in Plain Sight
The core of this vulnerability is a bypass of the mitigations for CVE-2024-4990. In that previous episode, the developers realized that letting users define arbitrary classes in configuration arrays was a bad idea. They added checks to ensure that only safe, expected classes were loaded. But here's the kicker: they didn't disable the mechanism itself, and they didn't account for built-in Yii2 behaviors that could be weaponized. Enter yii\behaviors\AttributeTypecastBehavior.
This behavior sounds incredibly boring, which makes it the perfect assassin. Its legitimate purpose is to automatically convert model attributes to specific types (e.g., ensuring a string "123" becomes an integer 123) before saving to the database. It does this by accepting an array called attributeTypes, where the key is the attribute name and the value is a PHP callable (function) used to perform the conversion.
Do you see the logic flaw yet? In PHP, system, exec, and passthru are valid callables. If an attacker can inject this behavior into a component and define a "typecast" rule that maps an attribute containing a shell command to the system function, the framework will helpful "convert" that shell command by executing it. The attacker doesn't need to upload a webshell; they just need to ask the framework to "typecast" their malicious input using the OS kernel.
The Code: Anatomy of the Injection
Let's look at the mechanism. In a standard Yii2 application, a component configuration might look like this:
[
'class' => 'some\safe\Component',
'someProperty' => 'someValue'
]However, because Craft CMS allows administrative actions (like apply-layout-element-settings) to pass complex JSON blobs that eventually hydrate these components, we can inject the magic keys. The vulnerable code blindly accepts the configuration array and hands it off to the framework. The specific gadget chain relies on the AttributeTypecastBehavior. Here is the logic flow visualized:
The vulnerability isn't in a specific line of bad code, but rather in the absence of sanitization for reserved framework keys. The AttributeTypecastBehavior class implementation (native to Yii2) looks roughly like this (simplified):
public function typecastAttributes()
{
foreach ($this->attributeTypes as $attribute => $type) {
// $type is the attacker-controlled callable (e.g., 'system')
// $value is the attacker-controlled string (e.g., 'id')
$this->owner->$attribute = call_user_func($type, $value);
}
}By binding this method to a wildcard event (on *) or a standard lifecycle event (beforeSave), the attacker ensures execution happens immediately.
The Exploit: Crafting the Poisoned Apple
To exploit this, an attacker needs authenticated access to the Craft CMS Control Panel. This lowers the severity slightly (it's not unauthenticated RCE), but in the world of targeted attacks, compromising an admin credential via phishing or credential stuffing is Monday's work. Once inside, we target endpoints that process layout elements or card previews, as these consume complex JSON configurations.
We construct a JSON payload that does three things simultaneously: attaches the behavior, configures the malicious callback, and sets the payload. Here is what the actual JSON body looks like:
{
"as exploit": {
"class": "yii\\behaviors\\AttributeTypecastBehavior",
"attributeTypes": {
"payload_attr": ["system"]
},
"typecastBeforeSave": true
},
"on *": ["self::beforeSave"],
"payload_attr": "id > /tmp/pwned.txt"
}When this payload hits the server:
as exploit: Yii attachesAttributeTypecastBehaviorto the component.- Configuration: The behavior is told to use
systemas the "typecasting" function for the attributepayload_attr. on *: We bind thebeforeSavemethod (which triggers the typecasting) to any event, ensuring it fires during the component's initialization or rendering lifecycle.- Execution: The value
id > /tmp/pwned.txtis passed tosystem(). Game over.
The Fix: Sanitizing the Magic
The remediation strategy adopted by Pixel & Tonic (the creators of Craft CMS) was straightforward and brutal: stop trusting the magic keys. In versions 5.8.21 and 4.16.17, they introduced a new method, Component::cleanseConfig(). This method acts as a gatekeeper before any configuration array is passed to Yii's object factories.
Code analysis of the patch shows a recursive stripping operation:
// craft/helpers/Component.php
public static function cleanseConfig(array $config): array
{
// Recursively remove 'on' and 'as' keys
foreach ($config as $key => $value) {
if (is_string($key) && (str_starts_with($key, 'as ') || str_starts_with($key, 'on '))) {
unset($config[$key]);
} elseif (is_array($value)) {
$config[$key] = self::cleanseConfig($value);
}
}
return $config;
}This approach is robust because it attacks the root cause—the configuration injection mechanism itself—rather than playing Whac-A-Mole with dangerous classes. By removing as (behaviors) and on (events), the attacker is left with a standard data array that cannot modify the object's logic or execution flow. If you are running Craft CMS, applying this patch is mandatory. If you cannot patch immediately, you must restrict access to the Control Panel to trusted IPs only, though even that is a temporary stopgap.
Official Patches
Fix Analysis (1)
Technical Appendix
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:HAffected Systems
Affected Versions Detail
| Product | Affected Versions | Fixed Version |
|---|---|---|
Craft CMS Pixel & Tonic | < 5.8.21 | 5.8.21 |
Craft CMS Pixel & Tonic | < 4.16.17 | 4.16.17 |
| Attribute | Detail |
|---|---|
| Attack Vector | Network (Authenticated) |
| Impact | Remote Code Execution (RCE) |
| CVSS v3.1 | 8.8 (High) |
| CWE ID | CWE-502 (Deserialization of Untrusted Data) |
| Exploit Status | PoC Available / Weaponized |
| Framework | Yii2 |
MITRE ATT&CK Mapping
The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.
Known Exploits & Detection
Vulnerability Timeline
Subscribe to updates
Get the latest CVE analysis reports delivered to your inbox.