CVE-2026-27739
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Angular is a TypeScript-based web development platform for building scalable single-page and server-side rendered applications. It provides a modular architecture, powerful dependency injection, and built-in tools for building modern, performant, and maintainable applications across web, mobile, and desktop environments.
A Server-Side Request Forgery (SSRF) vulnerability (CVE-2026-27739) has been identified in the Angular SSR request handling pipeline. The vulnerability exists because Angular’s internal URL reconstruction logic directly trusts and consumes user-controlled HTTP headers specifically the Host and X-Forwarded-* family to determine the application's base origin without any validation of the destination domain.
Per OWASP: In a Server-Side Request Forgery (SSRF) attack, the attacker can abuse functionality on the server to read or update internal resources. The attacker can supply or modify a URL which the code running on the server will read or submit data to, and by carefully selecting the URLs, the attacker may be able to read server configuration such as AWS metadata, connect to internal services like http enabled databases or perform post requests towards internal services which are not intended to be exposed.
This issue affects multiple Angular packages with server-side rendering capabilities, including @angular/ssr @nguniversal/common, and @nguniversal/express-engine. Workarounds and patched releases are available for most affected packages.
Details
Module Info
- Product: Angular
- Affected packages: @angular/ssr, @nguniversal/common, @nguniversal/express-engine
- Affected versions:
- @angular/ssr —
- >=21.2.0-next.0 <21.2.0-rc.1,
- >=21.0.0-next.0 <21.1.5,
- >=20.0.0-next.0 <20.3.17,
- >=19.0.0-next.0 <19.2.21
- @nguniversal/common — <= 16.2.0
- @nguniversal/express-engine — <= 16.2.0
- @angular/ssr —
- GitHub repositories:
- Published packages:
- https://www.npmjs.com/package/@angular/ssr
- https://www.npmjs.com/package/@nguniversal/common
- https://www.npmjs.com/package/@nguniversal/express-engine
- Package manager: npm
- Fixed in:
- OSS Angular CLI v21.2.0, v21.1.5, v20.3.17, v19.2.21
Vulnerability Info
Specifically, the framework didn't have checks for the following:
- Host Domain: The Host and X-Forwarded-Host headers were not checked to belong to a trusted origin. This allows an attacker to redefine the "base" of the application to an arbitrary external domain.
- Path & Character Sanitization: The X-Forwarded-Host header was not checked for path segments or special characters, allowing manipulation of the base path for all resolved relative URLs.
- Port Validation: The X-Forwarded-Port header was not verified as numeric, leading to malformed URI construction or injection attacks.
This vulnerability manifests in two primary ways:
- Implicit Relative URL Resolution: Angular's HttpClient resolves relative URLs against this unvalidated and potentially malformed base origin. An attacker can "steer" these requests to an external server or internal service.
- Explicit Manual Construction: Developers injecting the REQUEST object to manually construct URLs (for fetch or third-party SDKs) directly inherit these unsanitized values. By accessing the Host / X-Forwarded-* headers, the application logic may perform requests to attacker-controlled destinations or malformed endpoints.
Mitigation
Users of affected Angular packages should apply one of the following mitigations:
- Upgrade to a patched version of the affected packages:
- @angular/ssr — patched releases available
- @nguniversal/common — no patch currently available; apply other mitigations listed below
- @nguniversal/express-engine — no patch currently available; apply other mitigations listed below
- Apply a workaround:
- Use Absolute URLs: Avoid using req.headers for URL construction. Instead, use trusted variables for your base API paths.
- Implement Strict Header Validation (Middleware): If you cannot upgrade immediately, implement a middleware in your server.ts to enforce numeric ports and validated hostnames.
const ALLOWED_HOSTS = new Set(['your-domain.com']);
app.use((req, res, next) => {
const hostHeader = (req.headers['x-forwarded-host'] ?? req.headers['host'])?.toString();
const portHeader = req.headers['x-forwarded-port']?.toString();
if (hostHeader) {
const hostname = hostHeader.split(':')[0];
// Reject if hostname contains path separators or is not in allowlist
if (/^[a-z0-9.:-]+$/i.test(hostname) ||
(!ALLOWED_HOSTS.has(hostname) && hostname !== 'localhost')) {
return res.status(400).send('Invalid Hostname');
}
}
// Ensure port is strictly numeric if provided
if (portHeader && !/^\d+$/.test(portHeader)) {
return res.status(400).send('Invalid Port');
}
next();
});
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
Credits
Yenya030 (finder)