CVE-2026-111754
Patch Available.
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.
An open redirect vulnerability (CVE-2026-111754) has been identified in the URL resolution of @angular/platform-server used during Server-Side Rendering (SSR), which allows attackers to craft request URLs that cause the server to redirect users to an arbitrary external domain. Because the crafted paths look like safe relative paths, they can also slip past application-level checks that only reject URLs starting with //.
Per OWASP: Unvalidated redirects and forwards are possible when a web application accepts untrusted input that could cause the web application to redirect the request to a URL contained within untrusted input. By modifying untrusted URL input to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials.
This issue affects multiple versions of Angular.
Details
Module Info
- Product: Angular
- Affected packages:
@angular/platform-server - Affected versions:
- <=19.2.25
- >=20.0.0 <20.3.33
- >=21.0.0 <21.2.25
- >=22.0.0 <22.2.1
- GitHub repository: https://github.com/angular/angular
- Published packages: https://www.npmjs.com/package/@angular/platform-server
- Package manager: npm
- Fixed in:
- OSS Angular v20.3.33, v21.2.25 and v22.2.1
- NES for Angular
Vulnerability Info
This Medium-severity vulnerability is found in the @angular/platform-server package in multiple versions of Angular. When an application is rendered on the server, ServerPlatformLocation resolves the incoming request URL through the parseUrl helper (resolveUrl in later releases). That helper is meant to reject protocol-relative URLs unless allowProtocolRelative is set, but it only checks the raw input string, before the URL is normalized:
if (urlStr.startsWith('//')) {
if (!allowProtocolRelative) {
throw new Error(`Protocol relative URLs are not allowed in this context. URL: ${urlStr}`);
}
return new URL(urlStr, origin);
}
resolved = new URL(urlStr, origin);
if (!isSafeOriginChange(resolved, originUrl, urlStr, allowOriginChange)) {
throwSuspiciousUrlError(urlStr);
}
return resolved;An input such as /.//evil.test, /..//evil.test, or a router-serialized shape such as /.;/(//evil.test) does not start with //, so it passes the check. The WHATWG URL constructor then removes the dot-segment, and the resolved URL has the pathname //evil.test. The origin is unchanged, so isSafeOriginChange accepts it too. ServerPlatformLocation stores //evil.test as the current pathname. When @angular/ssr sees that the rendered URL differs from the router's final location, it writes that pathname into the Location header of an HTTP 302 response (Location: //evil.test). Browsers treat this as a protocol-relative URL and navigate off-origin to evil.test.
An unauthenticated attacker can exploit this when the router has parameter routes that match . and serialize secondary outlet groups, or when user-supplied navigation targets such as a returnUrl reach the router, and when any reverse proxy in front of the application passes dot-segments and semicolons through unchanged. Pure client-side applications that do not use server-side rendering are not affected.
Mitigation
Angular versions prior to 20 were already End-of-Life when this CVE was published and will not receive any updates to address this issue. For more information see here.
Users of the affected components should apply one of the following mitigations:
- Migrate affected applications to a patched version of Angular.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
Credits
- Jaime Burgos (finder)