symfony/ux-live-component: CSRF Protection Bypass — Accept Header is CORS-Safelisted
Description
Description
When using symfony/ux-live-component, methods annotated with #[LiveAction] are invokable from the browser and mutate server-side state via AJAX. Symfony\UX\LiveComponent\EventListener\LiveComponentSubscriber::isLiveComponentRequest() gated these invocations on the presence of Accept: application/vnd.live-component+html, with a code comment stating that this acted as a CSRF protection.
The Accept header is a CORS-safelisted request header, so a cross-origin fetch() can set it without triggering a preflight. The header therefore provided no CSRF protection. Any #[LiveAction] could be forged cross-origin against a victim's session.
In practice the attack is mitigated by SameSite=Lax session cookies (Symfony's default), but applications using SameSite=None, credentials: 'include' with a permissive cookie policy, or that have been pivoted from another same-origin vector remained exposed.
Resolution
isLiveComponentRequest() now additionally requires the request header X-Requested-With: XMLHttpRequest. This header is not CORS-safelisted, so the browser issues a preflight OPTIONS request for any cross-origin attempt; Symfony does not advertise CORS for LiveComponent endpoints, the preflight fails, and the real request is blocked before it reaches the application. The bundled Stimulus client already sends X-Requested-With on every LiveComponent request (RequestBuilder.ts), so standard usage is unaffected. Cross-origin callers must add X-Requested-With to their CORS Access-Control-Allow-Headers allow-list.
The patch for this issue is available here for branch 2.x (and forward-ported to 3.x).
Credits
Symfony would like to thank Anthropic (via Project Glasswing) for reporting the issue and Hugo Alliaume for providing the fix.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Affected products
1Patches
Vulnerability mechanics
Root cause
"The `Accept` header alone is a CORS-safelisted request header and therefore provides no CSRF protection for cross-origin requests."
Attack vector
An attacker can forge a cross-origin `fetch()` request that sets the `Accept: application/vnd.live-component+html` header — which is CORS-safelisted — and includes the victim's session cookies (if `SameSite` is not `Lax`/`Strict`). This triggers any `#[LiveAction]` method on the victim's behalf, mutating server-side state. The attack is mitigated by Symfony's default `SameSite=Lax` cookies, but remains exploitable when `SameSite=None` is used or when the attacker has already achieved same-origin execution via another vector. [ref_id=2]
Affected code
The vulnerability resides in `Symfony\UX\LiveComponent\EventListener\LiveComponentSubscriber::isLiveComponentRequest()`. The method relied solely on the `Accept: application/vnd.live-component+html` header as a CSRF gate, but that header is CORS-safelisted and can be set cross-origin without a preflight. The patch modifies `src/LiveComponent/src/EventListener/LiveComponentSubscriber.php` to additionally require the `X-Requested-With: XMLHttpRequest` header.
What the fix does
The patch adds a check in `isLiveComponentRequest()` that rejects any request lacking the `X-Requested-With: XMLHttpRequest` header [patch_id=6625359]. Because `X-Requested-With` is not CORS-safelisted, the browser sends a preflight `OPTIONS` request for cross-origin attempts; Symfony does not respond with CORS headers for LiveComponent endpoints, so the preflight fails and the real request is never sent. The bundled Stimulus client already includes this header, so standard usage is unaffected. [ref_id=2]
Preconditions
- authThe victim's browser must have a valid session with the target Symfony application.
- configThe session cookie must not be protected by SameSite=Lax or SameSite=Strict (e.g., SameSite=None is configured, or the attacker already has same-origin script execution).
- networkThe attacker must be able to make the victim's browser send a cross-origin fetch() request to the LiveComponent endpoint.
Generated on Jun 19, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.