Listen to this Post
Vulnerability Type: DOM Clobbering via Client Hydration
CVE ID: (CVE ID Not Assigned)
Intro
During Server-Side Rendering (SSR) with hydration enabled (provideClientHydration()), Angular serializes its application state (like cached `HttpClient` responses) into the HTML. This state is embedded in a predictable ` JSON` object is parsed, and the data is used to rehydrate the client-side application.
This process is vulnerable to a DOM Clobbering attack. Because Angular relies solely on the predictable `id=”ng-state”` to find the state container, an attacker who can inject HTML into the page (via user input, CMS content, etc.) can create a malicious element with the same id, such as `
The critical risk arises from HTTP Transfer Cache Poisoning. By controlling the ` JSONcan be injected into Angular's `TransferState` cache. Specifically, the attacker can map a target API endpoint to a forged response. On the client side, when `HttpClient` checks `TransferState` before making a real request, it finds the poisoned cache entry and returns the attacker's forged data instead of calling the legitimate backend. Depending on how the app renders this data, the impact ranges from UI spoofing to Cross-Site Scripting (XSS).
<h2 style="color: blue;">DailyCVE Form</h2>
Platform: Angular
Version: 17.0.0 - 22.0.0
Vulnerability : DOM Clobbering
Severity: High
date: 2025-08-28
<h2 style="color: blue;">Prediction: 2026-02-15</h2>
<h2 style="color: blue;">What Undercode Say</h2>
Analysis of the DOM Clobbering vulnerability shows it's trivially exploitable if user input reaches DOM IDs:
Check for vulnerable element binding in Angular templates grep -r "\[id\]=" src/app/ --include=".html" Identify use of unsafe native element references grep -r "ElementRef" src/app/ --include=".ts"
<h2 style="color: blue;">The issue is rooted in `TransferState` restoration logic:</h2>
// Vulnerable call sequence in Angular's hydration process
const stateEl = document.getElementById('ng-state');
const rawJson = stateEl.textContent; // Attacker-controlled source
const stateData = JSON.parse(rawJson);
<h2 style="color: blue;">Exploit</h2>
An attacker injects a clobbered element prior to Angular’s hydration script:
<!-- Malicious input injected into the DOM -->
<a id="ng-state" href="javascript:alert('XSS')"></a>
<!-- Or an injected script tag -->
<div id="ng-state">{"https://api.example.com/user": {"name": "<img src=x onerror=alert(1)>"}}</div>
If the application uses `
="user.name"` without sanitization, the injected payload renders and executes. <h2 style="color: blue;">Protection</h2> <h2 style="color: blue;">1. Avoid Dynamic/User-Controlled IDs</h2> Never bind raw user input to `id` attributes. Always sanitize and prefix: [bash] <!-- Safe pattern --> <div [bash]="'safe_prefix_' + sanitizedInput">...</div>
<h2 style="color: blue;">2. Configure a Custom Application ID</h2>
Use a unique, unpredictable `APP_ID` to change the state element ID from the defaultng-state.
// app.config.ts
import { APP_ID } from '@angular/core';
export const appConfig = {
providers: [
{ provide: APP_ID, useValue: 'unique-obfuscated-app-id' },
provideClientHydration()
]
};
This changes the state element ID tounique-obfuscated-app-id-state`, breaking attacker predictions.
Impact
- HTTP Cache Poisoning: Attackers can forge API responses, leading to data injection into the application state.
- DOM-Based XSS: Malicious payloads in poisoned API responses can be rendered unsafely, leading to arbitrary JavaScript execution.
- Privilege Escalation & UI Hijacking: Spoofing user info or configuration endpoints can manipulate user sessions and redirect traffic.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

