GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

GHSA-34W5-C283-J9FG

Vulnerability from github – Published: 2026-06-19 19:34 – Updated: 2026-06-19 19:34
VLAI
Summary
symfony/ux-live-component: LiveComponentHydrator HMAC checksum lacks component and slot binding
Details

Description

In symfony/ux-live-component, a component's server-side state is exposed to the browser as a set of props (#[LiveProp]-annotated properties). Props marked writable: true can be freely changed by the client. Read-only props are round-tripped to the browser and back, and their integrity is protected by an HMAC so the client cannot tamper with them. Child components additionally receive a propsFromParent blob, also HMAC-signed.

The HMAC computed by Symfony\UX\LiveComponent\LiveComponentHydrator covered only the sorted prop key/value pairs. It didn't include the component name, the slot identifier (props vs propsFromParent), or any request context, and a single application-wide secret is used for every component. A signed blob the server minted for component A is therefore a valid signature for component B if the key names happen to match, and a props blob can be replayed in the propsFromParent slot (or the reverse). An attacker can use this to set a read-only prop on a target component to a value they were only ever allowed to choose as a writable prop on another component.

Resolution

The HMAC is now bound to its context: the component name and a slot identifier are included in the pre-image before hashing. Two constants (CHECKSUM_SLOT_PROPS and CHECKSUM_SLOT_PROPS_FROM_PARENT) name the two slots, and calculateChecksum(), verifyChecksum(), addChecksumToData(), and ChildComponentPartialRenderer thread these values through. Cross-component and cross-slot replays no longer verify.

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.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/ux-live-component"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.8.0"
            },
            {
              "fixed": "2.36.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Packagist",
        "name": "symfony/ux-live-component"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.0"
            },
            {
              "fixed": "3.1.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-49212"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-345"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T19:34:56Z",
    "nvd_published_at": null,
    "severity": "LOW"
  },
  "details": "### Description\n\nIn `symfony/ux-live-component`, a component\u0027s server-side state is exposed to the browser as a set of props (`#[LiveProp]`-annotated properties). Props marked `writable: true` can be freely changed by the client. Read-only props are round-tripped to the browser and back, and their integrity is protected by an HMAC so the client cannot tamper with them. Child components additionally receive a `propsFromParent` blob, also HMAC-signed.\n\nThe HMAC computed by `Symfony\\UX\\LiveComponent\\LiveComponentHydrator` covered only the sorted prop key/value pairs. It didn\u0027t include the component name, the slot identifier (`props` vs `propsFromParent`), or any request context, and a single application-wide secret is used for every component. A signed blob the server minted for component A is therefore a valid signature for component B if the key names happen to match, and a `props` blob can be replayed in the `propsFromParent` slot (or the reverse). An attacker can use this to set a read-only prop on a target component to a value they were only ever allowed to choose as a writable prop on another component.\n\n### Resolution\n\nThe HMAC is now bound to its context: the component name and a slot identifier are included in the pre-image before hashing. Two constants (`CHECKSUM_SLOT_PROPS` and `CHECKSUM_SLOT_PROPS_FROM_PARENT`) name the two slots, and `calculateChecksum()`, `verifyChecksum()`, `addChecksumToData()`, and `ChildComponentPartialRenderer` thread these values through. Cross-component and cross-slot replays no longer verify.\n\nThe patch for this issue is available [here](https://github.com/symfony/ux/commit/a224b5af3e2e33ee14ac71356ae0e0877900a81c) for branch 2.x (and forward-ported to 3.x).\n\n### Credits\n\nSymfony would like to thank Anthropic (via Project Glasswing) for reporting the issue and Hugo Alliaume for providing the fix.",
  "id": "GHSA-34w5-c283-j9fg",
  "modified": "2026-06-19T19:34:56Z",
  "published": "2026-06-19T19:34:56Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/symfony/ux/security/advisories/GHSA-34w5-c283-j9fg"
    },
    {
      "type": "WEB",
      "url": "https://github.com/symfony/ux/commit/a224b5af3e2e33ee14ac71356ae0e0877900a81c"
    },
    {
      "type": "WEB",
      "url": "https://github.com/FriendsOfPHP/security-advisories/blob/master/symfony/ux-live-component/CVE-2026-49212.yaml"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/symfony/ux"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:H/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "symfony/ux-live-component: LiveComponentHydrator HMAC checksum lacks component and slot binding"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…