CVE-2026-31823: Sylius/sylius Cross-Site Scripting Vulnerability
MODERATECVE-2026-31823 is a MODERATE (CVSS 4.8) cross-site scripting vulnerability (CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')) affecting Sylius/sylius libraries in the Packagist ecosystem. The issue involves sylius vulnerable to authenticated stored xss. Remediation is available by upgrading affected packages to version 2.0.16, 2.1.12, 2.2.3.
CVE-2026-31823 at a Glance
Security Impact
CVSS: 4.8
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N).
How to Fix CVE-2026-31823
To remediate this vulnerability, upgrade all affected Sylius/sylius dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade sylius/sylius to 2.0.16
Upgrade sylius/sylius to 2.1.12
Upgrade sylius/sylius to 2.2.3
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for sylius/sylius
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-31823, inspect your project dependencies for Sylius/sylius:
inspect dependencies for sylius/sylius
Analyze the terminal output to locate any version of Sylius/sylius in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.0.16), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'), where the product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. In Sylius/sylius, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-31823 Affected Sylius/sylius Versions
3 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
sylius/sylius
|
Packagist |
≥ 2.0.0
< 2.0.16
|
2.0.16
|
|
sylius/sylius
|
Packagist |
≥ 2.1.0
< 2.1.12
|
2.1.12
|
|
sylius/sylius
|
Packagist |
≥ 2.2.0
< 2.2.3
|
2.2.3
|
References
Frequently Asked Questions
What is CVE-2026-31823?
Which Sylius/sylius versions are affected?
What version fixes CVE-2026-31823?
Is sylius/sylius affected?
What is the CVSS score of CVE-2026-31823?
What CWE is associated with CVE-2026-31823?
How can I check Packagist dependencies for CVE-2026-31823?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-mx4q-xxc9-pf5q",
"modified" : "2026-03-11T20:33:00Z",
"published" : "2026-03-11T00:13:20Z",
"aliases" : [ "CVE-2026-31823" ],
"summary" : "Sylius Vulnerable to Authenticated Stored XSS",
"details" : "### Impact\n\nAn authenticated stored cross-site scripting (XSS) vulnerability exists in multiple places across the shop frontend and admin panel due to unsanitized entity names being rendered as raw HTML.\n\n**Shop breadcrumbs** (`shared/breadcrumbs.html.twig`): The `breadcrumbs` macro uses the Twig `|raw` filter on label values. Since taxon names, product names, and ancestor names flow directly into these labels, a malicious taxon name like `<img src=x onerror=alert('XSS')>` is rendered and executed as JavaScript on the storefront.\n\n**Admin product taxon picker** (`ProductTaxonTreeController.js`): The `rowRenderer` method interpolates `${name}` directly into a template literal building HTML, allowing script injection through taxon names in the admin panel.\n\n**Admin autocomplete fields** (Tom Select): Dropdown items and options render entity names as raw HTML without escaping, allowing XSS through any autocomplete field displaying entity names.\n\nAn **authenticated administrator** can inject arbitrary HTML or JavaScript via entity names (e.g. taxon name) that is persistently rendered for all users.\n\n### Patches\n\nThe issue is fixed in versions: 2.0.16, 2.1.12, 2.2.3 and above.\n\n### Workarounds\n\nOverride vulnerable templates and JavaScript controllers at the project level.\n\n---\n\n#### Step 1 — Override shop breadcrumbs template\n\n`templates/bundles/SyliusShopBundle/shared/breadcrumbs.html.twig`:\n\n```twig\n{% macro breadcrumbs(items) %}\n <ol class=\"breadcrumb\" aria-label=\"breadcrumbs\">\n {% for item in items %}\n <li class=\"breadcrumb-item fw-normal{{ item.active is defined and item.active ? ' active' }}\">\n {% if item.path is defined %}\n <a class=\"link-reset\" href=\"{{ item.path }}\" {{ item.test_attribute is defined ? sylius_test_html_attribute(item.test_attribute) }}>{{ item.label }}</a>\n {% else %}\n <span class=\"text-body-tertiary text-break\" {{ item.test_attribute is defined ? sylius_test_html_attribute(item.test_attribute) }}>{{ item.label }}</span>\n {% endif %}\n </li>\n {% endfor %}\n </ol>\n{% endmacro %}\n```\n\n#### Step 2 — Override order breadcrumbs template\n\n`templates/bundles/SyliusShopBundle/account/order/show/content/breadcrumbs.html.twig`:\n\n```twig\n{% from '@SyliusShop/shared/breadcrumbs.html.twig' import breadcrumbs as breadcrumbs %}\n\n{% set order = hookable_metadata.context.order %}\n\n<div class=\"col-12\">\n {{ breadcrumbs([\n { label: 'sylius.ui.home'|trans, path: path('sylius_shop_homepage')},\n { label: 'sylius.ui.my_account'|trans, path: path('sylius_shop_account_dashboard')},\n { label: 'sylius.ui.order_history'|trans, path: path('sylius_shop_account_order_index')},\n { label: '#'~order.number, active: true, test_attribute: 'order-number' }\n ]) }}\n</div>\n```\n\n#### Step 3 — Override ProductTaxonTreeController.js\n\nDisable the vendor controller in `assets/admin/controllers.json`:\n\n```diff\n \"product-taxon-tree\": {\n- \"enabled\": true,\n+ \"enabled\": false,\n \"fetch\": \"lazy\"\n },\n```\n\nCreate `assets/admin/controllers/product_taxon_tree_controller.js` — copy the original from `vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/Resources/assets/controllers/ProductTaxonTreeController.js` and apply the following change:\n\n```diff\n+ const escapeHtml = (str) => {\n+ const div = document.createElement('div');\n+ div.textContent = str;\n+ return div.innerHTML;\n+ };\n\n // in rowRenderer:\n- <span class=\"infinite-tree-title\">${name}</span>\n+ <span class=\"infinite-tree-title\">${escapeHtml(name)}</span>\n```\n\nRegister the patched controller in `assets/admin/bootstrap.js`:\n\n```js\nimport ProductTaxonTreeController from './controllers/product_taxon_tree_controller';\napp.register('sylius--admin-bundle--product-taxon-tree', ProductTaxonTreeController);\n```\n\n#### Step 4 — Add autocomplete XSS protection\n\n`assets/admin/scripts/autocomplete-xss-protection.js`:\n\n```js\nconst escapeHtml = (str) => {\n if (typeof str !== 'string') return str;\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n};\n\ndocument.addEventListener('autocomplete:pre-connect', (event) => {\n const options = event.detail.options;\n if (!options.render) return;\n\n const labelField = options.labelField || 'text';\n const wrapRenderer = (renderer) => {\n if (!renderer) return renderer;\n return (data, escape) => {\n const escaped = { ...data };\n if (escaped[labelField]) {\n escaped[labelField] = escapeHtml(escaped[labelField]);\n }\n return renderer(escaped, escape);\n };\n };\n\n if (options.render.item) options.render.item = wrapRenderer(options.render.item);\n if (options.render.option) options.render.option = wrapRenderer(options.render.option);\n});\n```\n\nImport in `assets/admin/entrypoint.js` **before** bootstrap:\n\n```diff\n+ import './scripts/autocomplete-xss-protection';\n import './bootstrap.js';\n```\n\n#### Step 5 — Rebuild assets\n\n```bash\nyarn encore dev # or: yarn encore production\n```\n\n### Reporters\n\nWe would like to extend our gratitude to the following individuals for their detailed reporting and responsible disclosure of this vulnerability:\n- Djibril Mounkoro (@whiteov3rflow)\n- Bartłomiej Nowiński (@bnBart)\n\n### For more information\n\nIf you have any questions or comments about this advisory:\n\n- Open an issue in [Sylius issues](https://github.com/Sylius/Sylius/issues?q=sort%3Aupdated-desc+is%3Aissue+is%3Aopen)\n- Email us at [security@sylius.com](mailto:security@sylius.com)",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Packagist",
"name" : "sylius/sylius"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "2.0.0"
}, {
"fixed" : "2.0.16"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 2.0.15"
}
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "sylius/sylius"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "2.1.0"
}, {
"fixed" : "2.1.12"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 2.1.11"
}
}, {
"package" : {
"ecosystem" : "Packagist",
"name" : "sylius/sylius"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "2.2.0"
}, {
"fixed" : "2.2.3"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 2.2.2"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/Sylius/Sylius/security/advisories/GHSA-mx4q-xxc9-pf5q"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-31823"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/Sylius/Sylius"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-79" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-03-11T00:13:20Z",
"nvd_published_at" : "2026-03-10T22:16:19Z"
}
}