CVE-2026-104871 Overview
CVE-2026-104871 is a path traversal vulnerability [CWE-22] in Angular Server-Side Rendering (SSR). The flaw affects the CommonEngine.retrieveSSGPage prerendered-page retrieval logic in @angular/ssr/node, and in @angular/ssr for versions 17 through 18. On Windows deployments, the engine accepts a relative request URL containing a backslash parent-traversal segment. An unauthenticated requester can retrieve a sibling prerendered HTML page when that page contains the Angular Static Site Generation (SSG) marker. The issue affects versions prior to 20.3.36, 21.2.23, and 22.1.7.
Critical Impact
Unauthenticated attackers can retrieve prerendered HTML content from sibling output directories whose names share the configured public-directory prefix on Windows deployments.
Affected Products
- @angular/ssr/node prior to version 20.3.36
- @angular/ssr/node prior to version 21.2.23 and 22.1.7
- @angular/ssr versions 17 through 18
Discovery Timeline
- 2026-10-02 - CVE-2026-104871 published to NVD
- 2026-10-06 - Last updated in NVD database
Technical Details for CVE-2026-104871
Vulnerability Analysis
The vulnerability resides in the prerendered page retrieval logic of Angular SSR's CommonEngine. When a request URL is passed to CommonEngine.render, the code constructs a URL using a non-special resolve:// base. This base preserves backslash characters in the input path rather than normalizing them. The resulting path is then combined with the configured public directory using path.join, which on Windows treats the backslash as a valid separator. A containment check using pagePath.startsWith(normalize(publicPath)) validates the resolved path against the public directory. The check is a prefix comparison and fails to enforce true directory containment.
Root Cause
The root cause is improper limitation of a pathname to a restricted directory [CWE-22]. The startsWith string comparison treats sibling directories that begin with the same prefix as valid. For example, if the public directory is C:\app\public, a resolved path pointing to C:\app\public-staging\page.html passes the check. The exploit requires a sibling output directory whose name shares the configured public-directory prefix and contains qualifying prerendered Angular HTML with the SSG marker.
Attack Vector
An unauthenticated attacker crafts a relative request URL containing a backslash-based parent-traversal segment. The request is routed to a Windows deployment that forwards the raw URL to CommonEngine.render. The engine resolves the path into a sibling directory that satisfies the flawed prefix check, then returns the prerendered HTML. The scope is limited: it does not permit arbitrary file read, and only files containing the Angular SSG marker are returned.
// Patch excerpt from packages/angular/ssr/node/src/common-engine/common-engine.ts
import { BootstrapContext } from '@angular/platform-browser';
import { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';
import * as fs from 'node:fs';
-import { dirname, join, normalize, resolve } from 'node:path';
+import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
import { URL } from 'node:url';
import { validateUrl } from '../../../src/utils/validation';
import { getAllowedHostsFromEnv } from '../environment-options';
Source: Angular CLI Commit Fix. The fix replaces normalize with relative and isAbsolute to perform a true containment check rather than a prefix string match.
Detection Methods for CVE-2026-104871
Indicators of Compromise
- HTTP request logs containing URL-encoded or raw backslash sequences (\, %5C) in the path component of requests to Angular SSR endpoints.
- Successful 200 responses returning HTML content whose path resolves outside the intended public directory.
- Repeated requests probing variations of the public directory name with sibling suffixes such as public-staging or public-backup.
Detection Strategies
- Inspect Node.js and reverse proxy access logs for request paths containing %5C, \, or ..\ sequences targeting SSR routes.
- Correlate requests to Windows-hosted Angular SSR applications with responses returning HTML containing Angular SSG markers.
- Review file system access telemetry on the SSR host for reads outside the configured public directory tree.
Monitoring Recommendations
- Enable verbose request logging on Node.js SSR hosts and forward logs to a centralized analytics platform for pattern analysis.
- Deploy web application firewall (WAF) rules that block or alert on backslash sequences in URL paths.
- Monitor the Angular SSR process for unexpected reads of files in directories adjacent to the configured publicPath.
How to Mitigate CVE-2026-104871
Immediate Actions Required
- Upgrade @angular/ssr to version 20.3.36, 21.2.23, or 22.1.7 depending on your major version track.
- Audit Windows SSR deployments for sibling directories that share a prefix with the configured public directory and rename them if present.
- Normalize incoming request URLs at a reverse proxy layer to reject backslash characters before they reach the Node.js runtime.
Patch Information
The issue is resolved in Angular CLI releases v20.3.36, v21.2.23, and v22.1.7. The code change replaces the startsWith(normalize(publicPath)) prefix check with a containment test using relative and isAbsolute from node:path. See the GitHub Security Advisory GHSA-7g7c-h8rr-7p6q for the complete advisory text.
Workarounds
- Pass absolute, pre-validated URLs to CommonEngine.render rather than relative request URLs taken from client input.
- Rename sibling output directories so they no longer share a prefix with the configured public directory.
- Deploy on a non-Windows host where path.join does not treat backslash as a path separator, if migration is feasible.
- Add a request-sanitization middleware that rejects any request path containing \ or %5C before dispatch to the SSR engine.
# Example npm upgrade commands
npm install @angular/ssr@20.3.36
npm install @angular/ssr@21.2.23
npm install @angular/ssr@22.1.7
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

