Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-49209

CVE-2026-49209: Symfony UX DoS Vulnerability

CVE-2026-49209 is a denial of service flaw in Symfony UX that allows authenticated attackers to exhaust server resources through unbounded batch requests. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-49209 Overview

CVE-2026-49209 is a resource exhaustion vulnerability in Symfony UX LiveComponent affecting versions from 2.5.0 up to 2.36.0 and 3.1.0. The BatchActionController::__invoke() method iterates over a client-supplied actions array and issues a full HttpKernel sub-request for each entry. Because the array size is never bounded, an authenticated client can submit a single _batch request containing thousands of actions. The server processes each action sequentially, exhausting CPU, memory, and database connections. The flaw is categorized as Uncontrolled Resource Consumption [CWE-770] and carries a CVSS 4.0 score of 5.3.

Critical Impact

An authenticated attacker can trigger denial of service against the application server by submitting a single crafted _batch request with an unbounded actions array.

Affected Products

  • Symfony UX LiveComponent 2.5.0 through 2.35.x
  • Symfony UX LiveComponent 3.0.0
  • Applications embedding Symfony\UX\LiveComponent\Controller\BatchActionController

Discovery Timeline

  • 2026-07-17 - CVE-2026-49209 published to NVD
  • 2026-07-20 - Last updated in NVD database

Technical Details for CVE-2026-49209

Vulnerability Analysis

Symfony UX LiveComponent exposes a _batch endpoint that lets clients group multiple component actions into a single HTTP request. The controller Symfony\UX\LiveComponent\Controller\BatchActionController::__invoke() decodes the JSON payload and loops through every entry in the actions array. For each entry, the controller dispatches a full HttpKernel sub-request that reruns middleware, service resolution, database queries, and component rendering. The controller applied no upper bound on the number of actions per request before the fix.

An authenticated client can therefore submit one request containing thousands of actions and force the worker to execute thousands of nested sub-requests. Each sub-request consumes worker time, PHP memory, and a database connection from the pool. A small number of concurrent _batch requests can saturate PHP-FPM workers and exhaust the database connection limit.

Root Cause

The root cause is missing input validation on the size of the actions array. The controller trusts the client to send a reasonable number of actions and does not enforce a server-side ceiling. The fix introduces a MAX_ACTIONS_PER_BATCH constant of 50 on both the PHP controller and the JavaScript live_controller.js, and the client-side code chunks pending actions accordingly.

Attack Vector

Exploitation requires network access and low-privilege authentication because _batch requests are typically accepted from any authenticated session that can interact with a LiveComponent. No user interaction is required beyond the initial session. The attacker crafts a JSON payload with a large actions array and posts it to the LiveComponent _batch route.

javascript
// Security patch in src/LiveComponent/assets/dist/live_controller.js
// Source: https://github.com/symfony/ux/commit/95e878d5257f13d6d652ca95e3ef6bb0934d674f

 		this.unsyncedInputsTracker.resetUnsyncedFields();
 		const filesToSend = {};
 		for (const [key, value] of Object.entries(this.pendingFiles)) if (value.files) filesToSend[key] = value.files;
+		const actionsToSend = this.pendingActions.slice(0, 50);
+		const remainingActions = this.pendingActions.slice(50);
 		const requestConfig = {
 			props: this.valueStore.getOriginalProps(),
-			actions: this.pendingActions,
+			actions: actionsToSend,
 			updated: this.valueStore.getDirtyProps(),
 			children: {},
 			updatedPropsFromParent: this.valueStore.getUpdatedPropsFromParent(),

The TypeScript client mirrors the server ceiling with an exported constant:

typescript
// Source: https://github.com/symfony/ux/commit/95e878d5257f13d6d652ca95e3ef6bb0934d674f

+// Must match BatchActionController::MAX_ACTIONS_PER_BATCH on the PHP side.
+export const MAX_ACTIONS_PER_BATCH = 50;

Detection Methods for CVE-2026-49209

Indicators of Compromise

  • POST requests to LiveComponent _batch endpoints containing more than 50 entries in the actions array.
  • Sudden spikes in PHP-FPM worker CPU time correlated with a single client session.
  • Database connection pool saturation or Too many connections errors from application workers.
  • Repeated _batch requests from the same authenticated session within short time windows.

Detection Strategies

  • Parse application access logs for _batch request bodies and flag payloads whose actions array length exceeds the MAX_ACTIONS_PER_BATCH ceiling of 50.
  • Correlate PHP-FPM slow log entries with LiveComponent route hits to surface abusive batches.
  • Alert when a single session drives worker saturation while other sessions remain idle.

Monitoring Recommendations

  • Track request duration percentiles for LiveComponent routes and alert on sustained regressions.
  • Monitor active database connections and PHP-FPM worker queue depth against baseline.
  • Rate-limit authenticated _batch requests per session at the reverse proxy tier.

How to Mitigate CVE-2026-49209

Immediate Actions Required

  • Upgrade symfony/ux-live-component to 2.36.0 for the 2.x branch or 3.1.0 for the 3.x branch.
  • Audit reverse proxy and WAF policies to cap request body size on LiveComponent routes.
  • Enforce per-session rate limits on _batch endpoints until the patched version is deployed.

Patch Information

The vulnerability is fixed in Symfony UX LiveComponent 2.36.0 and 3.1.0. The patch is delivered in commit 95e878d5257f13d6d652ca95e3ef6bb0934d674f and introduces MAX_ACTIONS_PER_BATCH = 50 on both the PHP controller and the JavaScript client. Details are available in the GitHub Security Advisory GHSA-mm82-c99c-h2cf, GitHub Release v2.36.0, and GitHub Release v3.1.0.

Workarounds

  • Deploy a WAF rule that rejects _batch requests where the actions JSON array exceeds 50 elements.
  • Lower PHP max_input_vars and request body limits for LiveComponent routes to constrain payload size.
  • Reduce PHP-FPM request_terminate_timeout so runaway batches are killed before exhausting workers.
bash
# Update composer dependency to a patched release
composer require symfony/ux-live-component:^2.36.0
# or, for the 3.x branch
composer require symfony/ux-live-component:^3.1.0

# Clear application cache after upgrade
php bin/console cache:clear

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.