GHSA-2fph-6v5w-89hh
Craft CMS is Vulnerable to Authenticated Remote Code Execution via Malicious Attached Behavior
Packages
| Ecosystem | Package | Affected | Fixed in |
|---|---|---|---|
| Packagist | craftcms/cms | >= 5.6.0, < 5.9.13 | 5.9.13 |
Details
As written in the advisory (Markdown source, shown as plain text).
## Summary
A Remote Code Execution (RCE) vulnerability exists in Craft CMS 5.x and 4.x that bypasses the security fixes for GHSA-7jx7-3846-m7w7 and GHSA-255j-qw47-wjh5. This vulnerability can be exploited by any authenticated user with control panel access.
The existing patches add `cleanseConfig()` to `assembleLayoutFromPost()` and various `FieldsController` actions to strip Yii2 behavior/event injection keys (`as ` and `on ` prefixed keys). However, the `fieldLayouts` parameter in `ElementIndexesController::actionFilterHud()` is passed directly to `FieldLayout::createFromConfig()` without any sanitization, enabling the same behavior injection attack chain.
## Impact
- **Attack Type**: Remote Code Execution (RCE)
- **Authentication Required**: Authenticated user with control panel access (`accessCp` permission)
## Vulnerability Details
### Root Cause
In `ElementIndexesController::actionFilterHud()` (line 493-494), the `fieldLayouts` body parameter is passed to `FieldLayout::createFromConfig()` without `cleanseConfig()`:
```php
// ElementIndexesController.php:485-494
if ($conditionConfig) {
$conditionConfig = Component::cleanseConfig($conditionConfig); // conditionConfig IS cleansed
$condition = $conditionsService->createCondition($conditionConfig);
} else {
$condition = $this->elementType()::createCondition();
}
if (!empty($fieldLayouts)) {
// fieldLayouts is NOT cleansed!
$condition->setFieldLayouts(array_map(
fn(array $config) => FieldLayout::createFromConfig($config),
$fieldLayouts
));
}
```
Note the inconsistency: `conditionConfig` is sanitized with `cleanseConfig()`, but `fieldLayouts` is not.
### Attack Chain
1. Send a `fieldLayouts` array containing config with `"as <name>"` prefixed keys
2. `FieldLayout::createFromConfig($config)` -> `new self($config)` -> `Model::__construct($config)`
3. `App::configure($this, $config)` processes each key
4. `"as rce"` key -> `Component::__set("as rce", $value)` -> `Yii::createObject($value)` -> instantiates `AttributeTypecastBehavior` and attaches it to the FieldLayout
5. `"on *"` key -> registers a wildcard event handler
6. `parent::__construct()` -> `init()` -> `setTabs([])` -> `getAvailableNativeFields()` -> `trigger(EVENT_DEFINE_NATIVE_FIELDS)`
7. The wildcard handler fires -> `AttributeTypecastBehavior::beforeSave()` -> `typecastAttributes()`
8. `$this->owner->typecastBeforeSave` -> resolved via `Component::__get()` -> returns the command string from the behavior's own property
9. `call_user_func([ConsoleProcessus::class, 'execute'], $command)` -> `shell_exec($command)`
### Prerequisites
- A user account with control panel access
References
External links from the advisory. They lead to third-party sites.
- https://github.com/craftcms/cms/security/advisories/GHSA-2fph-6v5w-89hh
- https://nvd.nist.gov/vuln/detail/CVE-2026-33157
- https://github.com/craftcms/cms/commit/97e90b4bdee369c1af3ca77a77531132df240e4e
- https://github.com/advisories/GHSA-255j-qw47-wjh5
- https://github.com/advisories/GHSA-7jx7-3846-m7w7
- https://github.com/craftcms/cms
- https://github.com/craftcms/cms/releases/tag/5.9.13