CVE-2026-49216 Overview
CVE-2026-49216 is a Cross-Site Scripting (XSS) vulnerability in Symfony UX, a JavaScript ecosystem for Symfony. The flaw exists in the symfony/ux-autocomplete Stimulus controller, which renders AJAX response items by interpolating text fields directly into HTML template literals. Attacker-controlled markup supplied through dropdown values executes in the browser of any user who opens an autocomplete widget backed by the same data source. Affected versions range from 2.2.0 through 2.36.0 and include 3.1.0. The issue is tracked under [CWE-79] and resolved in versions 2.36.0 and 3.1.0.
Critical Impact
Attackers can inject arbitrary HTML and JavaScript into shared autocomplete widgets, enabling session theft, credential harvesting, and unauthorized actions in the context of any user rendering the tainted data.
Affected Products
- Symfony UX symfony/ux-autocomplete versions 2.2.0 through 2.35.x
- Symfony UX symfony/ux-autocomplete version 3.0.0
- Applications embedding autocomplete widgets backed by user-supplied AJAX data
Discovery Timeline
- 2026-07-17 - CVE-2026-49216 published to NVD
- 2026-07-21 - Last updated in NVD database
Technical Details for CVE-2026-49216
Vulnerability Analysis
The vulnerability resides in the _createAutocompleteWithRemoteData() function of the Symfony UX Autocomplete Stimulus controller. The controller uses the Tom Select library and defines render.option and render.item callbacks that construct DOM strings using JavaScript template literals. The item[labelField] value is interpolated directly into the <div> element without HTML escaping. Any value delivered through the backing AJAX endpoint is parsed as HTML by the browser.
Attackers who can influence records exposed through the autocomplete endpoint can embed <script>, <img onerror=...>, or other executable markup. Victims trigger execution simply by opening the autocomplete dropdown. The attack requires user interaction, but no authentication is needed if the dropdown is reachable by unauthenticated users.
Root Cause
The render.option and render.item callbacks used template literal interpolation instead of the escape helper exposed by Tom Select. This produced unescaped HTML output whenever optionsAsHtmlValue was not explicitly enabled by the developer, contrary to safe-by-default expectations.
Attack Vector
An attacker persists malicious markup into any data field that appears as a label in a shared autocomplete component, for example a user profile name, tag, or organization title. When another user opens a page containing the autocomplete widget bound to that dataset, the malicious payload executes in their session context.
// Vulnerable rendering (before patch)
render: {
option: (item) => `<div>${item[labelField]}</div>`,
item: (item) => `<div>${item[labelField]}</div>`,
}
// Patched rendering (after fix)
render: {
option: (item, escape) =>
`<div>${this.optionsAsHtmlValue ? item[labelField] : escape(item[labelField])}</div>`,
item: (item, escape) =>
`<div>${this.optionsAsHtmlValue ? item[labelField] : escape(item[labelField])}</div>`,
}
Source: Symfony UX commit 842ae54
Detection Methods for CVE-2026-49216
Indicators of Compromise
- Autocomplete AJAX response payloads containing HTML tags such as <script>, <img>, <svg>, or inline event handlers (onerror, onload) inside label fields.
- Browser console errors or Content Security Policy (CSP) violations originating from pages that host symfony/ux-autocomplete widgets.
- Outbound requests from user browsers to unfamiliar domains immediately after loading pages that render autocomplete data.
Detection Strategies
- Inventory application dependencies for symfony/ux-autocomplete versions between 2.2.0 and 2.35.x, or 3.0.0, using Composer lock files or Software Composition Analysis tooling.
- Inspect stored records that populate autocomplete labels for HTML metacharacters (<, >, ", ') that were not properly sanitized on ingestion.
- Add server-side logging on autocomplete endpoints to capture response bodies for retrospective analysis.
Monitoring Recommendations
- Enable a strict Content Security Policy that blocks inline scripts and reports violations to a centralized collector.
- Correlate web application firewall (WAF) alerts on <script> or event-handler patterns in HTTP responses served by autocomplete routes.
- Monitor authentication logs for anomalous session usage that could indicate cookie theft via injected JavaScript.
How to Mitigate CVE-2026-49216
Immediate Actions Required
- Upgrade symfony/ux-autocomplete to version 2.36.0 (2.x branch) or 3.1.0 (3.x branch) via Composer.
- Audit all data fields consumed by autocomplete widgets and remove any stored HTML payloads.
- Review whether the optionsAsHtmlValue flag is intentionally enabled anywhere and confirm those inputs are trusted.
Patch Information
The fix landed in commit 842ae54bc74de389299f975f01aafae272cb0019 and shipped in Symfony UX v2.36.0 and Symfony UX v3.1.0. Full details are published in the GitHub Security Advisory GHSA-mwqm-4fw3-cjvr.
Workarounds
- Sanitize label fields server-side before returning autocomplete AJAX responses, stripping or encoding HTML.
- Enforce a Content Security Policy that disallows inline script execution to reduce exploitability until the patch is deployed.
- Restrict who can write to fields that feed autocomplete widgets, particularly in multi-tenant deployments.
# Upgrade Symfony UX Autocomplete via Composer
composer require symfony/ux-autocomplete:^2.36.0
# or for the 3.x branch
composer require symfony/ux-autocomplete:^3.1.0
# Rebuild frontend assets so the patched Stimulus controller is shipped
php bin/console asset-map:compile
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

