CVE-2026-27739: SSRF and Header Injection in Angular SSR Request Handling Pipeline
How Angular's URL reconstruction logic turned trusted headers into an attacker-controlled proxy
.png)
Open source powers the modern software stack, but its security depends on a shared commitment to finding and fixing weaknesses before they turn into incidents.
At HeroDevs, that's our mission: secure open source. We do it in two ways:
- Remediating known CVEs across critical ecosystems, and
- Proactively researching vulnerabilities before attackers can exploit them.
A critical Angular SSR vulnerability, CVE-2026-27739, was recently published with a CVSS v4 score of 9.2 (Critical). It affects all versions of @angular/ssr prior to 19.2.21, including every end-of-life (EOL) version of Angular. No community patches are available for Angular 18 and earlier If your applications are running Angular SSR on an EOLversion, you need to act now.
What is CVE-2026-27739?
CVE-2026-27739 is a Server-Side Request Forgery (SSRF) vulnerability in Angular's Server-Side Rendering (SSR) request handling pipeline. The root cause is straightforward: 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.
This means an attacker who can manipulate those headers can redefine the application’s "base" to an arbitrary external domain, effectively turning the Angular SSR server into an open proxy for internal network probing and credential theft.
This is not a niche configuration issue. Any Angular application using SSR with relative HttpClient URLs is potentially in scope.
Critical Severity, Broad Attack Surface
The CVSS v4 vector for this vulnerability is:
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:H/SI:L/SA:N
That breaks down to:
- Attack Vector: Network -- exploitable remotely
- Attack Complexity: Low -- no special conditions required
- Privileges Required: None -- no authentication needed
- User Interaction: None -- fully automated exploitation
- Confidentiality Impact: High -- both on the vulnerable system and subsequent systems
A 9.2 Critical rating is significant. This is a vulnerability that security scanners, compliance auditors, and SCA tools will flag immediately, and for good reason.
Root Cause: Unvalidated Header Consumption in createRequestUrl
The vulnerability lives in the createRequestUrl utility function in packages/angular/ssr/node/src/request.ts. This function is responsible for constructing the full request URL from the incoming Node.js request object. It reads the host and x-forwarded-host headers to determine the hostname and uses those values to build a URL object.
The problem: it does so without any validation. Specifically, the framework lacked checks for:
- Host Domain Validation: The Host and X-Forwarded-Host headers were not verified against a trusted origin allowlist. An attacker can redefine the application's base to any external domain.
- Path and 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, enabling malformed URI construction or injection attacks.
This tainted URL is then consumed by higher-level request handlers including AngularAppEngine.handle, AngularNodeAppEngine.handle, and CommonEngine.render, none of which performed validation before the patch.
How the Exploit Works
The vulnerability manifests in two primary ways:
1. Implicit Relative URL Resolution
When server-side Angular code makes an HttpClient request using a relative URL (e.g., this.http.get('/api/users')), the SSR engine must resolve that relative path into an absolute URL. It does this by reading the incoming request's headers to determine the base origin.
If an attacker sends a request with a crafted X-Forwarded-Host: evil.com header, Angular resolves /api/users against https://evil.com/api/users. The SSR server then sends the request, including any Authorization headers or session cookies, directly to the attacker's server.
2. Explicit Manual Construction
Developers who inject the REQUEST object to manually build URLs for fetch() calls or third-party SDK integrations directly inherit the unsanitized header values. Any URL constructed from req.headers['host'] or req.headers['x-forwarded-host'] carries the same injection risk.
What an Attacker Can Achieve
When successfully exploited, this vulnerability enables:
- Credential Exfiltration: Stealing Authorization headers, API keys, or session cookies by redirecting internal API calls to attacker-controlled servers.
- Internal Network Probing: Accessing cloud metadata endpoints (e.g., 169.254.169.254), internal databases, or private services not exposed to the public internet.
- Confidentiality Breach: Reading sensitive data processed within the application's server-side context.
Attack Preconditions
For an application to be vulnerable, these conditions must be true:
- The application uses Angular SSR (Server-Side Rendering).
- The application performs HttpClient requests using relative URLs OR manually constructs URLs using the unvalidated Host / X-Forwarded-* headers via the REQUEST object.
- The application server is reachable by an attacker who can influence these headers without strict validation from a front-facing proxy.
- The infrastructure (Cloud, CDN, or Load Balancer) does not sanitize or validate incoming headers.
These conditions are common. Many Angular SSR deployments use relative URLs for API calls, and many cloud or CDN configurations pass through X-Forwarded-* headers without stripping or validating them.
Affected Versions and Patch Status
This is where the picture gets especially concerning for teams running older Angular versions.

Angular versions 18 and earlier are EOL and do not receive community patches.Angular 18 reached full EOL in early 2026. Angular versions 4 through 17 have been EOL for even longer. If you are running SSR on any of these versions, the Angular open source community will not be providing a fix.
The @nguniversal packages (used in Angular versions prior to 17 for SSR) are also affected with no patch available.
Mitigation Guidance
If You Are on Angular 19, 20, or 21
Update @angular/ssr to the patched version immediately:
npm update @angular/ssr
Verify your installed version matches 19.2.21, 20.3.17, or 21.1.5+ (depending on your major version).
If You Are on Angular 18 or Earlier
There is no community patch. You have two options:
Option 1: Implement a Header Validation Middleware
Add strict validation in your server.ts to enforce trusted hostnames and numeric ports:
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];
if (!ALLOWED_HOSTS.has(hostname) && hostname !== 'localhost') {
return res.status(400).send('Invalid Hostname');
}
}
if (portHeader && !/^\d+$/.test(portHeader)) {
return res.status(400).send('Invalid Port');
}
next();
});
This is a workaround, not a fix. It shifts validation responsibility to the application developer and must be maintained as infrastructure changes.
Option 2: Get a Patched Version Through HeroDevs Never-Ending Support
HeroDevs provides secure, patched drop-in replacements for EOL Angular versions, including @angular/ssr and the legacy @nguniversal packages. NES for Angular is maintained by core contributors to the Angular framework and delivers security patches for CVEs like this one, even when the community has moved on.
Additional Hardening (All Versions)
Regardless of version, review your infrastructure:
- Use absolute URLs for server-side API calls instead of relative paths where possible.
- Configure your reverse proxy (Nginx, AWS ALB, Cloudflare) to strip or validate X-Forwarded-* headers before they reach your application.
Audit server-side code for any manual URL construction using req.headers.
Why This Matters for the Angular Ecosystem
Two aspects of this CVE are worth highlighting:
This is a framework-level vulnerability, not a developer mistake. The SSRF is not the result of a developer concatenating strings into URLs carelessly. It is baked into how Angular's SSR engine reconstructs request URLs. Developers who followed standard Angular patterns (using relative HttpClient URLs in SSR) were unknowingly exposed.
The EOL gap is real and growing. Angular 18 hit full EOL with no patch for this Critical-severity CVE. Angular 19's security support window closes in May 2026. Angular 20 follows in November 2026. For enterprise teams operating on multi-year upgrade cycles, the period gap between "end of community support" and "upgrade or migration finishes" is where risk concentrates.
Taking Action
CVE-2026-27739 is a textbook example of implicit trust gone wrong in a server-side framework. The exploit is simple, the impact is severe, and the attack surface is broad. For teams on supported Angular versions, patching is straightforward. For teams on EOL versions, the exposure is real and the clock is ticking.
If your organization depends on Angular SSR and cannot immediately upgrade to a supported version, HeroDevs Never-Ending Support for Angular provides the security patches you need to stay protected and compliant, without a forced migration.
Talk to our team to learn more, or get a custom quote.
.png)
.png)
.png)