Craft CMS - Multiple Stored Cross-Site Scripting in Settings Names and Field Options
Description
Craft CMS 4.x (>= 4.0.0-RC1, < 4.17.0-beta.1) and 5.x (>= 5.0.0-RC1, < 5.9.0-beta.1) contain multiple stored cross-site scripting vulnerabilities where settings names and field option labels are rendered without sanitization (e.g., via the checkbox.twig template, which used {{ label|raw }}). An authenticated administrator (with allowAdminChanges enabled) can inject malicious payloads into section names, volume names, user group names, global set names, generated field names, checkbox/radio option labels, and custom source labels, causing arbitrary JavaScript to execute in other users' control-panel sessions. Fixed in 4.17.0-beta.1 and 5.9.0-beta.1.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
2Patches
Vulnerability mechanics
Root cause
"User-supplied names and labels are rendered with `{{ label|raw }}` in Twig templates or via `.html()` in JavaScript UI helpers without HTML escaping, enabling stored cross-site scripting."
Attack vector
An authenticated administrator with `allowAdminChanges` enabled can inject arbitrary JavaScript into settings names or field option labels (e.g., section names, volume names, user group names, global set names, generated field names, checkbox/radio option labels, and custom source labels) [ref_id=3]. The payload is stored and later rendered without sanitization in control-panel pages such as field source checklists, user permission pages, user profile pages, and card attribute checklists [ref_id=3]. When another administrator visits the affected page, the injected script executes in their browser session, enabling actions such as session hijacking or further administrative actions [CWE-79].
Affected code
The vulnerability spans multiple Twig templates and JavaScript UI helpers. The primary sink is `templates/_includes/forms/checkbox.twig` and `templates/_includes/forms/radio.twig`, which rendered the `label` variable with `{{ label|raw }}` without escaping [ref_id=1][ref_id=2]. Additional sinks include `Craft.ui.createSelect()`, `Craft.ui.createCheckbox()`, and `Craft.GeneratedFieldsTable.Row`, which used `.html()` or `html:` to set option/label content from user-supplied names [ref_id=1][ref_id=2]. The patch also escapes labels in `previewPlaceholderHtml()` via `Html::encode()` [ref_id=1].
What the fix does
The patches remove the unsafe `|raw` filter from `checkbox.twig` and `radio.twig`, causing Twig's auto-escaping to encode the label [ref_id=1][ref_id=2]. In JavaScript, `Craft.ui.createSelect()` and `Craft.ui.createCheckbox()` now use `.text()` instead of `.html()` for the `label` property, and a new `labelHtml` property is introduced for cases where raw HTML is intentionally needed [ref_id=1][ref_id=2]. The `previewPlaceholderHtml()` method now calls `Html::encode()` on each label before rendering [ref_id=1]. These changes ensure that attacker-supplied names and labels are HTML-escaped by default, preventing script injection.
Preconditions
- authAttacker must be an authenticated administrator with access to settings pages.
- configThe `allowAdminChanges` config setting must be enabled (the default in production, per the advisory).
- inputAttacker must be able to create or edit one of the vulnerable settings (section, volume, user group, global set, field options, or custom sources).
Generated on Jun 22, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/craftcms/cms/commit/67780a778c6ec04e68e64a0b1177c168306144a2mitrepatch
- github.com/craftcms/cms/commit/943152d2246b36f12adf161a03b8695b773d9276mitrepatch
- github.com/craftcms/cms/security/advisories/GHSA-4mgv-366x-qxvxmitrevendor-advisory
- www.vulncheck.com/advisories/craft-cms-multiple-stored-cross-site-scripting-in-settings-names-and-field-optionsmitrethird-party-advisory
News mentions
0No linked articles in our index yet.