VDB
KO
LOW

GHSA-4m4j-hmqq-3gxm

symfony/ux-live-component: CSRF Protection Bypass — Accept Header is CORS-Safelisted

Details

### 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](https://fetch.spec.whatwg.org/#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](https://github.com/symfony/ux/commit/aed7493db2b4b7bf1f9c79b33cda544f06904b27) 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.

Are you affected?

Enter the version of the package you're using.

Affected packages

Packagist / symfony/ux-live-component
Introduced in: 2.22.0 Fixed in: 2.36.0
Fix composer require symfony/ux-live-component:^2.36.0
Packagist / symfony/ux-live-component
Introduced in: 3.0.0 Fixed in: 3.1.0
Fix composer require symfony/ux-live-component:^3.1.0

References