GitHub Advisoryadvisory · npm
GHSA-ff3f-86qr-9cv3 Angular Server-Side Rendering (SSR): Denial of Service via Numeric URL Matrix Parameters
HIGH
Official page ↗
- Aliases
- CVE-2026-101896
- Ecosystem
- npm
- Packages
- @angular/router
- Severity
- High
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
- Weaknesses
- CWE-400, CWE-770
- Reviewed
- 2026-09-30
Affected packages
• npm @angular/router: >= 22.0.0, < 22.2.0 → fixed in 22.2.0
• npm @angular/router: >= 21.0.0, < 21.2.24 → fixed in 21.2.24
• npm @angular/router: >= 20.0.0, < 20.3.32 → fixed in 20.3.32
• npm @angular/router: <= 19.2.25 (no fix yet)
Description
A denial of service (DoS) vulnerability was identified in `@angular/router` when Server-Side Rendering (SSR) is enabled on Node.js (V8).
When `@angular/router` parses incoming request URLs, it extracts path segments, matrix parameters, and child outlets into plain JavaScript objects (`Record`). When matrix parameter names or outlet names are numeric strings (such as `/a;990;2522`), the V8 JavaScript engine interprets them as array-indexed properties rather than named properties.
Under V8's internal property-storage heuristics, setting numeric keys on an initially empty object causes V8 to allocate a dense array backing store (`HOLEY_ELEMENTS`) sized to the maximum index rather than falling back to sparse dictionary storage. Specifically, assigning sequential or moderately large numeric keys (like `990` followed by `2522`) causes V8 to allocate a contiguous backing store of ~2,522 pointers (~20 KB to 25 KB of heap) for a single 11-byte segment.
Because each segment in a URL path allocates its own independent `parameters` object, an attacker can craft URLs with repeated numeric matrix parameters to achieve an asymmetric memory amplification factor of approximately ~350x.
Impact
Successful exploitation allows an unauthenticated remote attacker to exhaust the Node.js old-space heap with modest request volume, terminating the SSR worker with an unrecoverable `JavaScript heap out of memory` fatal error and causing a Denial of Service.
• High Amplification: A single 11-byte segment (`/a;990;2522`) consumes ~20 KB–25 KB of V8 heap.
• Low Concurrency Required:
• With 8 KB request paths (~740 segments, within default Nginx 8 KB buffer limits), as few as 12–22 concurrent requests crash a 256 MiB–512 MiB Node.js SSR worker.
• With smaller 1 KB–2 KB request paths (~90–180 segments), a burst of ~50–100 concurrent requests achieves the same heap exhaustion.
• Client-side SPAs Unaffected: Pure client-side Angular applications (Single Page Applications without SSR) are not vulnerable, as local browser memory consumption does not cross a security boundary.
Attack Preconditions & Vulnerable Configurations
An application is affected only if all of the following conditions are met:
• SSR Enabled: The application runs in a Server-Side Rendering environment powered by Node.js / V8.
• Direct Router Parsing: User-controlled request URLs are parsed by `@angular/router` during SSR.
• No Reverse-Proxy Semicolon/Segment Filtering: Upstream reverse proxies (Nginx, Cloudflare, ALB) forward URLs containing semicolons (`;`) and multiple path segments without stripping or rejecting them.
Exploit Payload Example
An attacker sends concurrent HTTP requests with repeated numeric matrix parameters:
```http
GET /a;990;2522/a;990;2522/a;990;2522/... HTTP/1.1
Host: example.com
```
Even with paths under 2 KB, overlapping requests during SSR will rapidly consume the V8 heap until the process crashes.
Patches
The issue is resolved by updating `@angular/router` to enforce V8 dictionary elements storage (`setUrlDerivedKey`) for numeric URL-derived keys (index >= 32). This prevents V8 from allocating oversized contiguous array backing stores while preserving route matching, parameter values, and component input bindings.
• `22.2.0`
• `21.2.24`
• `20.3.32`
Workarounds & Mitigations
If you cannot immediately upgrade to a patched version, apply one of the following mitigations at your edge or reverse proxy:
1. Block or Sanitize Matrix Parameters at the Reverse Proxy:
Configure your reverse proxy (e.g., Nginx, Cloudflare, or AWS WAF) to reject or strip semicolons (`;`) in request paths before forwarding requests to the Angular SSR service:
```nginx
# Nginx example: reject requests containing matrix parameters
if ($uri ~* ";") {
return 400;
}
```
2. Enforce Strict Path Segment Limits:
Reject requests with excessive path depth (e.g., more than 20–30 segments).
3. Increase Node.js Old Space:
Increase `--max-old-space-size` (e.g., to 2048 or 4096 MB) to increase the concurrency threshold required to exhaust memory, though this does not fully eliminate the vulnerability under sustained traffic.
Related
Alias · CVE (1)
- CVE-2026-101896 Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages. vulnerability
References
- https://github.com/angular/angular/security/advisories/GHSA-ff3f-86qr-9cv3 web
- https://github.com/angular/angular/issues/70716 web
- https://github.com/angular/angular/pull/70717 web
- https://github.com/angular/angular/commit/03872a80bcf1c89b2b04cdd3f444b2ee954da583 web
- https://github.com/angular/angular/commit/5af61216eab8bf4a6697a1d79bda3d857c06f89d web
- https://github.com/angular/angular/commit/ddfe21072ba32ca4cd9d7d3c6b7df66af81d58c4 web
- https://github.com/angular/angular package