GHSA-VFX2-HV2G-XJ5F

Vulnerability from github – Published: 2026-03-19 21:22 – Updated: 2026-03-27 20:49
VLAI?
Summary
Protocol-Relative URL Injection via Single Backslash Bypass in Angular SSR
Details

An Open Redirect vulnerability exists in @angular/ssr due to an incomplete fix for CVE-2026-27738. While the original fix successfully blocked multiple leading slashes (e.g., ///), the internal validation logic fails to account for a single backslash (\) bypass.

When an Angular SSR application is deployed behind a proxy that passes the X-Forwarded-Prefix header:

  • An attacker provides a value starting with a single backslash (e.g., \evil.com).
  • The internal validation failed to flag the single backslash as invalid.
  • The application prepends a leading forward slash, resulting in a Location header containing /\evil.com.
  • Modern browsers interpret the /\ sequence as //, treating it as a protocol-relative URL and redirecting the user to the attacker-controlled domain.

Furthermore, the response lacks the Vary: X-Forwarded-Prefix header, allowing the malicious redirect to be stored in intermediate caches (Web Cache Poisoning).

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.

Patches

  • 22.0.0-next.2
  • 21.2.3
  • 20.3.21

Workarounds

Until the patch is applied, developers should sanitize the X-Forwarded-Prefix header in their server.ts before the Angular engine processes the request:

app.use((req, res, next) => {
  const prefix = req.headers['x-forwarded-prefix'];
  if (typeof prefix === 'string') {
    // Sanitize by removing all leading forward and backward slashes
    req.headers['x-forwarded-prefix'] = prefix.trim().replace(/^[/\\]+/, '/');
  }
  next();
});

References

  • Fix: https://github.com/angular/angular-cli/pull/32771
  • Original CVE: CVE-2026-27738
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@angular/ssr"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "22.0.0-next.0"
            },
            {
              "fixed": "22.0.0-next.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@angular/ssr"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "21.0.0-next.0"
            },
            {
              "fixed": "21.2.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "@angular/ssr"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "20.0.0-next.0"
            },
            {
              "fixed": "20.3.21"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-33397"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-601"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-19T21:22:52Z",
    "nvd_published_at": "2026-03-26T15:16:38Z",
    "severity": "MODERATE"
  },
  "details": "An Open Redirect vulnerability exists in `@angular/ssr` due to an incomplete fix for CVE-2026-27738. While the original fix successfully blocked multiple leading slashes (e.g., `///`), the internal validation logic fails to account for a single backslash (`\\`) bypass.\n\nWhen an Angular SSR application is deployed behind a proxy that passes the `X-Forwarded-Prefix` header:\n\n- An attacker provides a value starting with a single backslash (e.g., `\\evil.com`).\n- The internal validation failed to flag the single backslash as invalid.\n- The application prepends a leading forward slash, resulting in a `Location` header containing `/\\evil.com`.\n- Modern browsers interpret the `/\\` sequence as `//`, treating it as a protocol-relative URL and redirecting the user to the attacker-controlled domain.\n\nFurthermore, the response lacks the `Vary: X-Forwarded-Prefix` header, allowing the malicious redirect to be stored in intermediate caches (Web Cache Poisoning).\n\n### Impact\nThis vulnerability allows attackers to conduct large-scale phishing and SEO hijacking:\n\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### Patches\n\n- 22.0.0-next.2\n- 21.2.3\n- 20.3.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];\n  if (typeof prefix === \u0027string\u0027) {\n    // Sanitize by removing all leading forward and backward slashes\n    req.headers[\u0027x-forwarded-prefix\u0027] = prefix.trim().replace(/^[/\\\\]+/, \u0027/\u0027);\n  }\n  next();\n});\n```\n\n\n### References\n\n- Fix: https://github.com/angular/angular-cli/pull/32771\n- Original CVE: CVE-2026-27738",
  "id": "GHSA-vfx2-hv2g-xj5f",
  "modified": "2026-03-27T20:49:01Z",
  "published": "2026-03-19T21:22:52Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/angular/angular-cli/security/advisories/GHSA-vfx2-hv2g-xj5f"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-33397"
    },
    {
      "type": "WEB",
      "url": "https://github.com/angular/angular-cli/pull/32771"
    },
    {
      "type": "ADVISORY",
      "url": "https://github.com/advisories/GHSA-xh43-g2fq-wjrj"
    },
    {
      "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": "Protocol-Relative URL Injection via Single Backslash Bypass in Angular SSR"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

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.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…