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…
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
- critical · 9.8CVE-2026-52778CVE-2026-52778: YesWiki CalcField Unsafe eval() Remote Code Execution and ReDoS
- criticalCVE-2026-27823CVE-2026-27823: EGroupware SmallPART Remote Code Execution via Auth Bypass and Path Traversal