GHSA-XH43-G2FQ-WJRJ
Vulnerability from github – Published: 2026-02-25 22:41 – Updated: 2026-02-25 22:41An Open Redirect vulnerability exists in the internal URL processing logic in Angular SSR. The logic normalizes URL segments by stripping leading slashes; however, it only removes a single leading slash.
When an Angular SSR application is deployed behind a proxy that passes the X-Forwarded-Prefix header, an attacker can provide a value starting with three slashes (e.g., ///evil.com).
- The application processes a redirect (e.g., from a router
redirectToor i18n locale switch). - Angular receives
///evil.comas the prefix. - It strips one slash, leaving
//evil.com. - The resulting string is used in the
Locationheader. - Modern browsers interpret
//as a protocol-relative URL, redirecting the user fromhttps://your-app.comtohttps://evil.com.
Impact
This vulnerability allows attackers to conduct large-scale phishing and SEO hijacking: - Scale: A single request can poison a high-traffic route, impacting all users until the cache expires. - SEO Poisoning: Search engine crawlers may follow and index these malicious redirects, causing the legitimate site to be delisted or associated with malicious domains. - Trust: Because the initial URL belongs to the trusted domain, users and security tools are less likely to flag the redirect as malicious.
Attack Preconditions
- The application must use Angular SSR.
- The application must have routes that perform internal redirects.
- The infrastructure (Reverse Proxy/CDN) must pass the
X-Forwarded-Prefixheader to the SSR process without sanitization. - The cache must not vary on the
X-Forwarded-Prefixheader.
Patches
- 21.2.0-rc.1
- 21.1.5
- 20.3.17
- 19.2.21
Workarounds
Until the patch is applied, developers should sanitize the X-Forwarded-Prefix header in theirserver.ts before the Angular engine processes the request:
app.use((req, res, next) => {
const prefix = req.headers['x-forwarded-prefix']?.trim();
if (prefix) {
// Sanitize by removing all leading slashes
req.headers['x-forwarded-prefix'] = prefix.replace(/^[/\\]+/, '/');
}
next();
});
Resources
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c 21.2.0-rc.0"
},
"package": {
"ecosystem": "npm",
"name": "@angular/ssr"
},
"ranges": [
{
"events": [
{
"introduced": "21.2.0-next.0"
},
{
"fixed": "21.2.0-rc.1"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@angular/ssr"
},
"ranges": [
{
"events": [
{
"introduced": "21.0.0-next.0"
},
{
"fixed": "21.1.5"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@angular/ssr"
},
"ranges": [
{
"events": [
{
"introduced": "20.0.0-next.0"
},
{
"fixed": "20.3.17"
}
],
"type": "ECOSYSTEM"
}
]
},
{
"package": {
"ecosystem": "npm",
"name": "@angular/ssr"
},
"ranges": [
{
"events": [
{
"introduced": "19.0.0-next.0"
},
{
"fixed": "19.2.21"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-27738"
],
"database_specific": {
"cwe_ids": [
"CWE-601"
],
"github_reviewed": true,
"github_reviewed_at": "2026-02-25T22:41:57Z",
"nvd_published_at": "2026-02-25T17:25:40Z",
"severity": "MODERATE"
},
"details": "An Open Redirect vulnerability exists in the internal URL processing logic in Angular SSR. The logic normalizes URL segments by stripping leading slashes; however, it only removes a single leading slash.\n\nWhen an Angular SSR application is deployed behind a proxy that passes the `X-Forwarded-Prefix` header, an attacker can provide a value starting with three slashes (e.g., `///evil.com`).\n\n1. The application processes a redirect (e.g., from a router `redirectTo` or i18n locale switch).\n2. Angular receives `///evil.com` as the prefix.\n3. It strips one slash, leaving `//evil.com`.\n4. The resulting string is used in the `Location` header.\n5. Modern browsers interpret `//` as a protocol-relative URL, redirecting the user from `https://your-app.com` to `https://evil.com`.\n\n\n### Impact\nThis vulnerability allows attackers to conduct large-scale phishing and SEO hijacking:\n- **Scale:** A single request can poison a high-traffic route, impacting all users until the cache expires.\n- **SEO Poisoning:** Search engine crawlers may follow and index these malicious redirects, causing the legitimate site to be delisted or associated with malicious domains.\n- **Trust:** Because the initial URL belongs to the trusted domain, users and security tools are less likely to flag the redirect as malicious.\n\n### Attack Preconditions\n\n- The application must use Angular SSR.\n- The application must have routes that perform internal redirects.\n- The infrastructure (Reverse Proxy/CDN) must pass the `X-Forwarded-Prefix` header to the SSR process without sanitization.\n- The cache must not vary on the `X-Forwarded-Prefix` header.\n\n### Patches\n- 21.2.0-rc.1\n- 21.1.5\n- 20.3.17\n- 19.2.21\n\n### Workarounds\nUntil the patch is applied, developers should sanitize the `X-Forwarded-Prefix` header in their`server.ts` before the Angular engine processes the request:\n\n```ts\napp.use((req, res, next) =\u003e {\n const prefix = req.headers[\u0027x-forwarded-prefix\u0027]?.trim();\n if (prefix) {\n // Sanitize by removing all leading slashes\n req.headers[\u0027x-forwarded-prefix\u0027] = prefix.replace(/^[/\\\\]+/, \u0027/\u0027);\n }\n next();\n});\n\n```\n\n### Resources\n- [Report](https://github.com/angular/angular-cli/issues/32501)\n- [Fix](https://github.com/angular/angular-cli/pull/32521)",
"id": "GHSA-xh43-g2fq-wjrj",
"modified": "2026-02-25T22:41:57Z",
"published": "2026-02-25T22:41:57Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/angular/angular-cli/security/advisories/GHSA-xh43-g2fq-wjrj"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-27738"
},
{
"type": "WEB",
"url": "https://github.com/angular/angular-cli/issues/32501"
},
{
"type": "WEB",
"url": "https://github.com/angular/angular-cli/pull/32521"
},
{
"type": "WEB",
"url": "https://github.com/angular/angular-cli/commit/f086eccc36d10cf01c426e35864bc32e1e292323"
},
{
"type": "PACKAGE",
"url": "https://github.com/angular/angular-cli"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N",
"type": "CVSS_V4"
}
],
"summary": "Angular SSR has an Open Redirect via X-Forwarded-Prefix"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.