CVE-2026-33397: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-33397 is a Protocol-Relative URL Injection (Open Redirect) vulnerability in the @angular/ssr npm package, classified as an incomplete fix for the prior CVE-2026-27738. The flaw allows unauthenticated network attackers to redirect users to attacker-controlled domains by injecting a single backslash (\) into the X-Forwarded-Prefix HTTP header, bypassing the validation introduced in the previous patch. Affected versions include @angular/ssr on the 20.x branch (< 20.3.21), 21.x branch (< 21.2.3), and 22.x branch (< 22.0.0-next.2). The advisory was published on March 19, 2026, with NVD publication on March 26, 2026. It carries a CVSS v3.1 score of 6.1 (Medium) and a CVSS v4.0 score of 6.9 (Medium) (Github Advisory).

Technical details

The root cause is CWE-601 (URL Redirection to Untrusted Site / Open Redirect), stemming from an incomplete input validation regex (INVALID_PREFIX_REGEX) in @angular/ssr's internal validation logic (packages/angular/ssr/src/utils/validation.ts). The prior fix for CVE-2026-27738 blocked multiple leading slashes (e.g., ///) but failed to account for a single backslash (\). When a proxy forwards the X-Forwarded-Prefix header with a value like \evil.com, Angular SSR's validation does not flag it as invalid; the application then prepends a forward slash, producing a Location header of /\evil.com. Modern browsers interpret /\ as //, treating it as a protocol-relative URL and silently redirecting users to the attacker's domain. Additionally, the absence of a Vary: X-Forwarded-Prefix response header enables the poisoned redirect to be cached by intermediate proxies, amplifying the attack's reach (Github Advisory, Fix PR).

Impact

Successful exploitation enables large-scale phishing, credential theft, and malware distribution by silently redirecting users from a trusted domain to an attacker-controlled site. Because the initial URL belongs to the legitimate domain, users and security tools are less likely to detect the malicious redirect. The compounding web cache poisoning vector means a single crafted request can affect all users served from a poisoned cache entry until it expires, and search engine crawlers may index the malicious redirects, causing SEO poisoning and potential delisting of the legitimate site (Github Advisory).

Exploitability

No public proof-of-concept exploit code or evidence of in-the-wild exploitation has been reported as of the time of this report (Feedly). The vulnerability was discovered and reported by security researcher VenkatKwest via a Google OSS VRP report (Fix PR). The EPSS score is approximately 0.039% (Feedly data), indicating a low near-term exploitation probability. The CVE is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. Exploitation requires the target application to use Angular SSR, have routes performing internal redirects, and be deployed behind a proxy that forwards the X-Forwarded-Prefix header without sanitization.

Exploitation steps

  1. Reconnaissance: Identify Angular SSR applications deployed behind a reverse proxy or CDN that forwards the X-Forwarded-Prefix header. Look for applications running @angular/ssr versions 20.x < 20.3.21, 21.x < 21.2.3, or 22.x < 22.0.0-next.2.
  2. Identify redirect routes: Find application routes that trigger internal redirects (e.g., redirectTo in Angular router configuration or i18n locale switches), as these are the paths that generate Location headers.
  3. Craft malicious request: Send an HTTP request to a redirect-triggering route with a manipulated X-Forwarded-Prefix header containing a single backslash followed by the attacker's domain:
    GET /some-redirect-route HTTP/1.1
    Host: target-app.com
    X-Forwarded-Prefix: \evil.com
  4. Trigger redirect generation: The Angular SSR validation logic fails to reject the backslash-prefixed value; the application prepends a forward slash, producing a Location: /\evil.com response header.
  5. Browser interprets as protocol-relative URL: Modern browsers treat /\evil.com as //evil.com, redirecting the victim to https://evil.com.
  6. Cache poisoning (optional amplification): Because the response lacks Vary: X-Forwarded-Prefix, intermediate caches store the poisoned redirect. Subsequent legitimate users requesting the same route from the cache are also redirected to the attacker's domain without any further attacker interaction (Github Advisory, Fix PR).

Indicators of compromise

  • Network: HTTP requests to Angular SSR redirect routes containing an X-Forwarded-Prefix header value starting with a backslash (e.g., \evil.com or \attacker-domain.tld); HTTP responses with Location headers matching the pattern /\<external-domain>.
  • Logs: Web server or proxy access logs showing requests to redirect-triggering routes with unusual X-Forwarded-Prefix header values containing backslashes; cache hit responses for redirect routes serving Location: /\<domain> values.
  • Cache/Proxy: Cached redirect responses pointing to external domains not belonging to the application's own domain; absence of Vary: X-Forwarded-Prefix in cached redirect responses from affected application versions.

Mitigation and workarounds

Upgrade @angular/ssr to the patched versions: 20.3.21 (20.x branch), 21.2.3 (21.x branch), or 22.0.0-next.2 (22.x branch). The fix updates INVALID_PREFIX_REGEX to reject prefixes starting with a backslash and adds the Vary: X-Forwarded-Prefix header to redirect responses (Fix PR). As a temporary workaround before patching, add the following middleware in server.ts to sanitize the header before Angular processes it:

app.use((req, res, next) => {
  const prefix = req.headers['x-forwarded-prefix'];
  if (typeof prefix === 'string') {
    req.headers['x-forwarded-prefix'] = prefix.trim().replace(/^[/\\]+/, '/');
  }
  next();
});

Additionally, configure reverse proxies or CDNs to strip or sanitize the X-Forwarded-Prefix header before forwarding requests to the Angular SSR process (Github Advisory).

Community reactions

The vulnerability was reported by researcher VenkatKwest through Google's OSS Vulnerability Reward Program and acknowledged by the Angular team, who merged the fix on March 17, 2026 (Fix PR). The advisory was published by Angular maintainer alan-agius4 on March 19, 2026. Community reaction has been limited, with the CVE appearing in standard vulnerability tracking feeds and databases shortly after disclosure, but no significant broader media coverage or notable researcher commentary beyond the original report has been identified.

Additional resources


Source: This report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-966w-4vpf-p7hcHIGH7.1
  • JavaScript logoJavaScript
  • @aloma.io/aloma
NoYesOct 25, 2026
GHSA-mrwp-f3q8-3g9pMEDIUM5.9
  • JavaScript logoJavaScript
  • follow-redirects
NoYesOct 25, 2026
GHSA-hfm3-x63j-7fxpHIGHN/A
  • JavaScript logoJavaScript
  • @payload-auth-link/migrate
NoYesOct 25, 2026
GHSA-6244-vvv9-76f5MEDIUMN/A
  • JavaScript logoJavaScript
  • @payload-auth-link/plugin
NoYesOct 25, 2026
GHSA-q53q-qg98-p9jfHIGHN/A
  • JavaScript logoJavaScript
  • llm-fw
NoYesOct 25, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management