{"id":"CVE-2026-27738","aliases":["GHSA-xh43-g2fq-wjrj"],"url":"https://o3.security/vulnerability/CVE-2026-27738","summary":"Angular SSR has an Open Redirect via X-Forwarded-Prefix","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) => {\n  const prefix = req.headers['x-forwarded-prefix']?.trim();\n  if (prefix) {\n    // Sanitize by removing all leading slashes\n    req.headers['x-forwarded-prefix'] = prefix.replace(/^[/\\\\]+/, '/');\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)","published":"2026-02-25T16:40:44.724Z","modified":"2026-08-12T03:51:22.975128436Z","cvss":null,"epss":{"score":0.00302,"percentile":0.22506,"asOf":"2026-09-07"},"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"npm","name":"@angular/ssr","fixedVersion":"21.2.0-rc.1"},{"ecosystem":"npm","name":"@angular/ssr","fixedVersion":"21.1.5"},{"ecosystem":"npm","name":"@angular/ssr","fixedVersion":"20.3.17"},{"ecosystem":"npm","name":"@angular/ssr","fixedVersion":"19.2.21"}],"fix":{"url":"https://github.com/angular/angular-cli/commit/877f017ace4b83277d773aa37f5813e5e9faec7e","label":"angular/angular-cli@877f017"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/27xxx/CVE-2026-27738.json"},{"type":"ADVISORY","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":"REPORT","url":"https://github.com/angular/angular-cli/issues/32501"},{"type":"FIX","url":"https://github.com/angular/angular-cli/commit/877f017ace4b83277d773aa37f5813e5e9faec7e"},{"type":"FIX","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"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:22.975128436Z"}}