Symfony UX 2.36.0 is a security release for the 2.x branch: it fixes seven vulnerabilities in the LiveComponent and Autocomplete packages, two of them rated medium severity. If your application depends on symfony/ux-live-component or symfony/ux-autocomplete, upgrade as soon as possible. The same fixes are also available on the 3.x branch through Symfony UX 3.1.0.

Medium severity

Two cross-site scripting issues are fixed in this release.

The Autocomplete Stimulus controller rendered AJAX response items by interpolating the text field directly into the dropdown's HTML, so any markup contained in the response was executed by the browser. When the dropdown values came from user-supplied content, an attacker could craft a string that triggered stored XSS for any other user who later opened a page with an autocomplete widget backed by the same data. The remote-data renderers now HTML-escape values by default. Endpoints that legitimately return HTML, for example to highlight the search term, can opt back in with the new options_as_html: true option (CVE-2026-49216).

LiveComponent re-renders interpolated the child component tag name, taken from client-controlled JSON, into the response without validation, allowing arbitrary HTML, including <script> tags, to be injected on any re-render of a component that contains at least one child. The default Accept header gate made this mostly a defense-in-depth gap, but it became directly exploitable on applications with a relaxed CORS policy. The child tag is now validated against a strict HTML tag-name pattern and anything that isn't a valid tag is dropped (CVE-2026-49210).

Low severity

The LiveComponent endpoint gated #[LiveAction] invocations on the Accept: application/vnd.live-component+html header as a CSRF measure, but that header is CORS-safelisted and can be set by a cross-origin fetch() without a preflight, so it offered no protection. The endpoint now also requires X-Requested-With: XMLHttpRequest, which is not CORS-safelisted and forces a preflight that fails for cross-origin attempts. The bundled Stimulus client already sends this header, so standard usage is unaffected; cross-origin callers must add it to their CORS allow-list (CVE-2026-49215).

A #[LiveProp] typed as a date with no explicit format was hydrated with the permissive DateTime constructor, which accepts relative strings such as "now" or "+10 years". A client could push a writable date prop to an arbitrary point in time and slip past time-based business checks. Format-less date props are now parsed strictly as RFC 3339, matching the format already emitted on the way out (CVE-2026-49208).

The _batch controller issued a full sub-request for every entry in the client-supplied actions array without bounding its size, so a single request with thousands of actions could exhaust CPU, memory, and database connections. The number of actions per batch is now capped at 50, and the JavaScript client splits larger batches into multiple requests so legitimate usage is unaffected (CVE-2026-49209).

The HMAC protecting read-only LiveComponent props covered only the prop key/value pairs, not the component name or the slot the props belong to. A signed blob minted for one component was therefore a valid signature for another component with matching prop names, and a props blob could be replayed in the propsFromParent slot. The HMAC pre-image now includes the component name and a slot identifier, so cross-component and cross-slot replays no longer verify (CVE-2026-49212).

The Autocomplete entity endpoint built its LIKE expression by wrapping the query in %...% without escaping the SQL wildcards %, _ and \. Since the endpoint is public by default and searches every property of the entity, an unauthenticated user could send % to match every row or use the endpoint as a blind boolean oracle against columns the application never meant to expose. Those characters are now escaped and matched literally through an explicit ESCAPE clause (CVE-2026-49211).

Credits

We would like to thank Pascal Cescon, Anthropic (via Project Glasswing) and Alex Ashkov for reporting these issues, and Pascal Cescon and Hugo Alliaume for providing the fixes.

Full Changelog

  • CVE-2026-49215 [LiveComponent] Require X-Requested-With header to prevent CSRF (@Kocal)
  • CVE-2026-49216 [Autocomplete] Fix XSS via unescaped AJAX response data (@Kocal)
  • CVE-2026-49208 [LiveComponent] Parse format-less date LiveProps strictly with RFC 3339 (@Kocal)
  • CVE-2026-49209 [LiveComponent] Cap the number of actions per _batch request (@Kocal)
  • CVE-2026-49210 [LiveComponent] Reject malicious child component tags (@Kocal)
  • CVE-2026-49212 [LiveComponent] Bind HMAC checksum to component name and slot (@Kocal)
  • CVE-2026-49211 [Autocomplete] Escape LIKE wildcards in the search query (@Amoifr)
Published in #Releases #Symfony UX