CVE-2026-56382: Craft CMS RCE via Yii2 Event Handler Injection in FieldsController
An authenticated Craft CMS admin can execute arbitrary PHP code by injecting a Yii2 event handler into a POST parameter that the card-preview endpoint passes directly to the object factory without san
The problem
The `actionRenderCardPreview()` method in `FieldsController` reads the `fieldLayoutConfig` POST body and spreads it directly into `Craft::createObject()` to build a `FieldLayout` instance. No call to `Component::cleanseConfig()` was made, so Yii2 "on eventName" keys were accepted as legitimate event handler registrations.
Any admin with a valid session and CSRF token can POST a config containing `on init` set to any callable PHP function. When Yii2 constructs the component and fires the `init` event, the callable executes immediately, with the output (including `phpinfo` environment variables such as `CRAFT_SECURITY_KEY` and database credentials) returned in the HTTP response.
Proof of concept
A working proof-of-concept for this issue in craftcms/cms, with the exact payload below.
POST /index.php?p=admin/actions/fields/render-card-preview HTTP/1.1
Host: target.example.com
Content-Type: application/x-www-form-urlencoded
Cookie: CraftSessionId=<valid-session-cookie>
CSRF_TOKEN=<valid-csrf-token>&fieldLayoutConfig[on+init]=phpinfoThe root cause is CWE-94: the `fieldLayoutConfig` array was spread into `Craft::createObject()` verbatim. Yii2 treats any config key matching the pattern `on <eventName>` as an event handler registration, so `on init` becomes a registered listener that fires during `Component::init()`.
The patch (commit 27f55886) wraps the input in `Component::cleanseConfig()` before spreading it, which strips all keys prefixed with `on ` or `as ` before they reach the Yii2 object factory. This is the same pattern that was missing here but correctly applied in the nearby `_fldComponent()` method and in sibling controllers (EntryTypesController, ElementIndexesController).
Because `phpinfo()` is a valid PHP callable, the basic PoC leaks full environment state with no further setup. Replacing it with `shell_exec` or `system` escalates to full OS command execution.
The fix
Update `craftcms/cms` to version 5.9.14 or later. The fix is a one-line change: wrap the user-supplied `$fieldLayoutConfig` array in `Component::cleanseConfig()` before passing it to `Craft::createObject()`. If immediate upgrade is not possible, restrict admin-panel access to trusted networks and rotate `CRAFT_SECURITY_KEY` and database credentials as a precaution.
Related research
- highCVE-2026-55794CVE-2026-55794: Craft CMS Authenticated RCE via Twig Injection in Referer Header
- highCVE-2026-55790CVE-2026-55790: Craft CMS DOM XSS via Poisoned GitHub Issue Title in CraftSupport Widget
- criticalCVE-2026-27823CVE-2026-27823: EGroupware SmallPART Remote Code Execution via Auth Bypass and Path Traversal
- highCVE-2026-40187CVE-2026-40187: EGroupware Authenticated RCE via eTemplate eval Injection