Angular Client Hydration DOM Clobbering & Response-Cache Poisoning
Date: 2026-06
Affected: npm/@angular/core, npm/@angular/core, npm/@angular/core
Attack vector: xss
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-54267
CWE: CWE-471
CWE-79

To optimize client-side bootstrap in Server-Side Rendered (SSR) environments, Angular supports **Hydration** via `provideClientHydration()`. During SSR, Angular serializes the application's runtime state (such as cached `HttpClient` responses) and outputs it into the HTML stream as a `<script>` tag with a predictable identifier: ```html <script type="application/json" id="ng-state"> {"some-api-url": {"body": ...}} </script> ```` During client bootstrap, Angular recovers this state by looking up the element via `document.getElementById('ng-state')` and parsing its text content. Because the DOM element lookup for the state container is predictable and relies solely on the ID selector (`ng-state`), it is susceptible to **DOM Clobbering**. If the application binds untrusted user input or CMS content to element properties such as `id` (e.g., `<div [id]="userInput">` or `<a id="ng-state">`) *before* the genuine `<script>` tag is parsed by the browser, the attacker-controlled element takes precedence in the DOM lookup. During hydration, when Angular calls `document.getElementById('ng-state')`, the browser returns the attacker's clobbered element. Angular then attempts to parse the text content or attributes of this clobbered element as JSON. ### Impact By clobbering the state element, the attacker can inject a custom JSON payload into Angular's `TransferState` cache. The most critical exploitation vector is poisoning the **HTTP Transfer Cache**. 1. The attacker injects a


Mitigations:

Architectural layers (MAESTRO):