GHSA-4MGV-366X-QXVX
Vulnerability from github – Published: 2026-03-03 20:58 – Updated: 2026-03-03 20:58Overview of all XSS Reports
Multiple stored XSS vulnerabilities were found in Craft CMS. They were split into 4 reports as follows:
| Report | What's Vulnerable | Why Separate |
|---|---|---|
| This Report (1) | Multiple settings names | Twig Template: _includes/forms/checkbox.twig |
| Report 2 | Entry Types Name | Twig Template: _includes/forms/editableTable.twig |
| Report 3 | Card Attributes in Field Layout | helpers/Cp.php |
| Report 4 (Commerce) | Product Type Name | Source in Commerce, sink in CMS - will report this one via Commerce GHSA |
Reports 2, 3, and 4 are clearly distinct locations. For this report (Report 1), it was not clear whether to split or consolidate these 7 bugs. The bug report was consolidated and the final categorization should be left to the judgement of the user.
Note: This overview is only in this Report. Other reports only reference this one.
Summary
Stored XSS in multiple settings. Names/labels are rendered without sanitization via checkbox.twig template which uses {{ label|raw }}.
Affected Sources
| # | Source (injection point) | Sink (where payload reflects) |
|---|---|---|
| 1 | Section Name (/admin/settings/sections) |
Entries field -> Sources checklist |
| 2 | Volume Name (/admin/settings/assets/volumes/{vol_id}) |
Assets field -> Sources checklist |
| 3 | User Group Name (/admin/settings/users/groups) |
Users field -> Sources, User permissions page |
| 4 | Global Set Name (/admin/settings/globals) |
User permissions page |
| 5 | Generated Fields Name (Volumes, Users, etc.) | Card Attributes checkboxes |
| 6 | Checkboxes & Radio Buttons Field Option Label (/admin/settings/fields) |
User profile pages |
| 7 | Custom Sources Label (/admin/users -> Customize Sources) |
Users field -> Sources checklist |
Proof of Concept
Required Permissions (Attacker)
- Admin access
allowAdminChangesis enabled in production, which is against our security recommendations.
Bugs 1-3: Section, Volume, User Group Names
- Log in as admin.
- Inject payload in one of these:
- Settings -> Sections -> Create/edit section -> Name
- Settings -> Assets -> Volumes -> Create/edit volume -> Name
- Settings -> Users -> User Groups -> Create/edit group -> Name
- Set Name to:
<img src=x onerror="alert('XSS')">
- Save.
- Go to Settings -> Fields -> Create new field.
- To trigger the XSS payload: Set Field Type to "Entries" (for Sections), "Assets" (for Volumes), or "Users" (for User Groups). The alert fires when the Sources checkbox list renders.
Note: User Group Name also reflects on User permissions page under User Groups section (/admin/users/{id}/permissions).
Bug 4: Global Set Name
- Go to Settings -> Globals (
/admin/settings/globals). - Create/edit a Global Set, set Name to payload.
- Save.
- Go to Users -> Edit any user -> Permissions tab (
/admin/users/{id}/permissions). - Alert fires because our payload got rendered in the "Global Sets" permissions section without encoding/sanitization.
Bug 5: Generated Fields Name
- Go to Settings -> Assets -> Volumes -> Create/Edit a volume.
- Scroll to Generated Fields section.
- Add a field, set Name to payload:
<img src=x onerror="alert('XSS')">
- Save & Notice the alert. The payload renders in the Card Attributes checkbox list below it.
Bug 6: Checkboxes/Radio Buttons Option Label
- Go to Settings -> Fields (
/admin/settings/fields). - Create new field, set Field Type to "Checkboxes" or "Radio Buttons".
- In Field Options, add an option with Label set to payload.
- Save the field.
- Go to Settings -> Users -> User Profile Fields (
/admin/settings/users/fields). - Add the created field to the layout and save.
- Alert fires on any user profile page (
/admin/users/{id}).
Bug 7: Custom Sources Label
- Go to Users (
/admin/users). - Click the three dots icon -> Customize Sources.
- Create a new custom source, set Label to payload.
- Save.
- Go to Settings -> Fields -> Create new field.
- Set Field Type to "Users".
- Alert fires in the Sources checkbox list.
Resources
https://github.com/craftcms/cms/commit/943152d2246b36f12adf161a03b8695b773d9276 https://github.com/craftcms/cms/commit/67780a778c6ec04e68e64a0b1177c168306144a2
{
"affected": [
{
"package": {
"ecosystem": "Packagist",
"name": "craftcms/cms"
},
"ranges": [
{
"events": [
{
"introduced": "5.0.0-RC1"
},
{
"fixed": "5.9.0-beta.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "Packagist",
"name": "craftcms/cms"
},
"ranges": [
{
"events": [
{
"introduced": "4.0.0-RC1"
},
{
"fixed": "4.17.0-beta.1"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [],
"database_specific": {
"cwe_ids": [
"CWE-79"
],
"github_reviewed": true,
"github_reviewed_at": "2026-03-03T20:58:07Z",
"nvd_published_at": null,
"severity": "LOW"
},
"details": "## Overview of all XSS Reports\n\nMultiple stored XSS vulnerabilities were found in Craft CMS. They were split into **4 reports** as follows:\n\n| Report | What\u0027s Vulnerable | Why Separate |\n|--------|-------------------|--------------|\n| **This Report (1)** | Multiple settings names | Twig Template: `_includes/forms/checkbox.twig` |\n| **Report 2** | Entry Types Name | Twig Template: `_includes/forms/editableTable.twig` |\n| **Report 3** | Card Attributes in Field Layout | `helpers/Cp.php` |\n| **Report 4 (Commerce)** | Product Type Name | Source in Commerce, sink in CMS - will report this one via Commerce GHSA |\n\nReports 2, 3, and 4 are clearly distinct locations. For this report (Report 1), it was not clear whether to split or consolidate these 7 bugs. The bug report was consolidated and the final categorization should be left to the judgement of the user.\n\n**Note:** This overview is only in this Report. Other reports only reference this one.\n\n---\n## Summary\n\nStored XSS in multiple settings. Names/labels are rendered without sanitization via `checkbox.twig` template which uses `{{ label|raw }}`.\n\n---\n## Affected Sources\n\n| # | Source (injection point) | Sink (where payload reflects) |\n| --- | ------------------------------------------------------------------------ | --------------------------------------------- |\n| 1 | Section Name (`/admin/settings/sections`) | Entries field -\u003e Sources checklist |\n| 2 | Volume Name (`/admin/settings/assets/volumes/{vol_id}`) | Assets field -\u003e Sources checklist |\n| 3 | User Group Name (`/admin/settings/users/groups`) | Users field -\u003e Sources, User permissions page |\n| 4 | Global Set Name (`/admin/settings/globals`) | User permissions page |\n| 5 | Generated Fields Name (Volumes, Users, etc.) | Card Attributes checkboxes |\n| 6 | Checkboxes \u0026 Radio Buttons Field Option Label (`/admin/settings/fields`) | User profile pages |\n| 7 | Custom Sources Label (`/admin/users` -\u003e Customize Sources) | Users field -\u003e Sources checklist |\n\n---\n## Proof of Concept\n\n### Required Permissions (Attacker)\n- Admin access\n- `allowAdminChanges` is enabled in production, which is against our [security recommendations](https://craftcms.com/knowledge-base/securing-craft).\n\n### Bugs 1-3: Section, Volume, User Group Names\n\n1. Log in as admin.\n2. Inject payload in one of these:\n - **Settings** -\u003e **Sections** -\u003e Create/edit section -\u003e **Name**\n - **Settings** -\u003e **Assets** -\u003e **Volumes** -\u003e Create/edit volume -\u003e **Name**\n - **Settings** -\u003e **Users** -\u003e **User Groups** -\u003e Create/edit group -\u003e **Name**\n3. Set **Name** to:\n```html\n\u003cimg src=x onerror=\"alert(\u0027XSS\u0027)\"\u003e\n```\n4. Save.\n5. Go to **Settings** -\u003e **Fields** -\u003e Create new field.\n6. To trigger the XSS payload: Set **Field Type** to \"Entries\" (for Sections), \"Assets\" (for Volumes), or \"Users\" (for User Groups). The alert fires when the Sources checkbox list renders.\n\n**Note:** User Group Name also reflects on **User permissions page** under **User Groups** section (`/admin/users/{id}/permissions`).\n\n---\n\n### Bug 4: Global Set Name\n\n1. Go to **Settings** -\u003e **Globals** (`/admin/settings/globals`).\n2. Create/edit a Global Set, set **Name** to payload.\n3. Save.\n4. Go to **Users** -\u003e Edit any user -\u003e **Permissions** tab (`/admin/users/{id}/permissions`).\n5. Alert fires because our payload got rendered in the \"Global Sets\" permissions section without encoding/sanitization.\n\n---\n\n### Bug 5: Generated Fields Name\n\n1. Go to **Settings** -\u003e **Assets** -\u003e **Volumes** -\u003e Create/Edit a volume.\n2. Scroll to **Generated Fields** section.\n3. Add a field, set **Name** to payload:\n```html\n\u003cimg src=x onerror=\"alert(\u0027XSS\u0027)\"\u003e\n```\n4. Save \u0026 Notice the alert. The payload renders in the **Card Attributes** checkbox list below it.\n\n---\n\n### Bug 6: Checkboxes/Radio Buttons Option Label\n\n1. Go to **Settings** -\u003e **Fields** (`/admin/settings/fields`).\n2. Create new field, set **Field Type** to \"Checkboxes\" or \"Radio Buttons\".\n3. In **Field Options**, add an option with **Label** set to payload.\n4. Save the field.\n5. Go to **Settings** -\u003e **Users** -\u003e **User Profile Fields** (`/admin/settings/users/fields`).\n6. Add the created field to the layout and save.\n7. Alert fires on any user profile page (`/admin/users/{id}`).\n\n---\n\n### Bug 7: Custom Sources Label\n\n1. Go to **Users** (`/admin/users`).\n2. Click the three dots icon -\u003e **Customize Sources**.\n3. Create a new custom source, set **Label** to payload.\n4. Save.\n5. Go to **Settings** -\u003e **Fields** -\u003e Create new field.\n6. Set **Field Type** to \"Users\".\n7. Alert fires in the Sources checkbox list.\n\n## Resources\n\nhttps://github.com/craftcms/cms/commit/943152d2246b36f12adf161a03b8695b773d9276\nhttps://github.com/craftcms/cms/commit/67780a778c6ec04e68e64a0b1177c168306144a2",
"id": "GHSA-4mgv-366x-qxvx",
"modified": "2026-03-03T20:58:07Z",
"published": "2026-03-03T20:58:07Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/craftcms/cms/security/advisories/GHSA-4mgv-366x-qxvx"
},
{
"type": "WEB",
"url": "https://github.com/craftcms/cms/commit/67780a778c6ec04e68e64a0b1177c168306144a2"
},
{
"type": "WEB",
"url": "https://github.com/craftcms/cms/commit/943152d2246b36f12adf161a03b8695b773d9276"
},
{
"type": "PACKAGE",
"url": "https://github.com/craftcms/cms"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "Craft CMS Vulnerable to Stored XSS in Settings Names and Field Options"
}
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.