~/f4n6 $ grep -r "Angular XSRF token leak CVE-2025-66035 bypasses protection via URL parsing flaws" ./investigations/ --include="*.md"

Angular XSRF token leak CVE-2025-66035 bypasses protection via URL parsing flaws

Jeff Davies 20 Oct 2026 7 min read

1. Executive summary

An incomplete fix for CVE-2025-66035 in @angular/common leaves the xsrfInterceptorFn in the Angular HTTP Client attaching the X-XSRF-TOKEN header to URLs that the browser resolves cross-origin, leaking the token to an attacker-controlled host. The flaw is rated CVSS 7.7 HIGH (CWE-201, CWE-359) and is not listed in CISA KEV; EPSS is 1%. The 20.3.x LTS branch kept the vulnerable regular expression until 20.3.34, while 21.0.3 and later and all 22.x releases already use a WHATWG origin comparison and are unaffected. For EMEA financial services, the exposure is confined to applications that pass user-influenced URLs into mutating HttpClient calls with XSRF protection enabled (the default), where a leaked token lets an attacker forge state-changing requests against the victim's session.

2. Regulatory framing

Article Trigger (the fact in this item) Practical impact
DORA Art. 28: ICT third-party risk, general principles The defect sits in a third-party JavaScript framework (@angular/common) that client applications embed and depend on for request security controls Firms need an inventory position on which applications run affected Angular versions and a route to the vendor fix through their dependency management process
DORA Art. 30: key contractual provisions with ICT third-party providers Remediation depends on the framework maintainer shipping a patched release (20.3.34) and on the firm's ability to consume it Where Angular support is contracted, the contract should give the firm the right to receive security fixes and version information on a defined timeline

3. Technical analysis & attack chain

The vulnerability is a parser differential. Angular's XSRF interceptor decides whether a request is same-origin using a regular expression, and the browser decides where the request actually goes using the WHATWG URL parser. The two disagree on a set of URL forms, and the interceptor's answer is the one that governs whether the token is attached.

The chain, as confirmed in the advisory:

  1. The application has XSRF protection enabled. This is the HttpClient default, so most applications are in scope unless they have turned it off.
  2. The attacker causes the application to issue a state-changing request (POST, PUT, DELETE, PATCH) to a URL the attacker controls, for example /\attacker.example/api or //attacker.example/api.
  3. xsrfInterceptorFn tests the URL against const ABSOLUTE_URL_REGEX = /^(?:https?:)?\/\//i. The crafted URL does not match, so the interceptor classifies it as a relative same-origin URL and attaches the X-XSRF-TOKEN header.
  4. The browser passes the same string to fetch() or XMLHttpRequest.open(), which resolve it with the WHATWG URL parser. For http: and https: schemes that parser normalises the input before resolving the authority, and the request is dispatched to evil.example.
  5. The attacker's server receives the request with the victim's valid X-XSRF-TOKEN header, provided its CORS configuration permits the request and the custom header.
  6. With the token in hand, the attacker forges state-changing requests against the victim's session, defeating the XSRF protection the token was meant to provide.

The URL forms that slip past the regex fall into three groups, all documented in the advisory:

  • Backslashes treated as forward slashes: /\evil.example/x, \\evil.example/x, \/evil.example/x, https:\\evil.example/x, https:/\evil.example/x.
  • Leading and trailing C0 control characters and spaces (<= 0x20) stripped by the parser: ' //evil.example/x', '\0//evil.example/x', '\x1f//evil.example/x'.
  • ASCII tab, newline and carriage return removed anywhere in the input: '/\t/evil.example/x', '/\n/evil.example/x', 'htt\tps://evil.example/x'.

The advisory names two workarounds for teams that cannot upgrade immediately: normalise outgoing URLs with new URL(url, window.location.origin) and check parsedUrl.origin === window.location.origin before passing dynamic URLs to mutating HttpClient calls, and stop passing untrusted or user-controlled URLs to those methods at all.

Related Angular SSR advisories describe a separate class of parser differential in @angular/platform-server, where resolveUrl/parseUrl ran String.prototype.trim() and stripped Unicode whitespace such as U+00A0 that the WHATWG parser keeps, turning a same-origin path into a protocol-relative cross-origin URL and leaking Authorization headers during server-side rendering (GHSA-f6mr-pjwc-34m4). Two further SSR advisories cover host allowlist bypass through a double-port URL such as http://evil.com:80:80/path that Node's URL.canParse rejects but Domino parses leniently (GHSA-xrxm-cp7j-8xf6), and hostname hijacking via absolute-form URLs mitigated by the allowedHosts option (GHSA-rfh7-fxqc-q52v). These are distinct defects with their own patch versions and are not the same vulnerability as CVE-2025-66035; they are relevant because a firm running Angular SSR may have several of these to remediate at once. The SSR advisories are single-sourced to the GitHub Security Advisory database and the patch-version lists should be checked against the vendor before planning an upgrade.

No exploitation in the wild, no threat actor and no malware are associated with CVE-2025-66035 in the available material. The EPSS score of 1% is consistent with a flaw that requires the application itself to route a user-influenced URL into a mutating request.

4. Mitigation & containment

P1 (within 24 hours)

  • Inventory every application built on @angular/common 20.3.x below 20.3.34. Check the lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml) rather than package.json ranges, since a caret range can resolve to a patched build while a pinned lockfile does not.
  • For each affected application, confirm whether any mutating HttpClient call (POST, PUT, DELETE, PATCH) takes a URL that is influenced by user input, a query parameter, a redirect target or server-supplied data. Applications that only call fixed literal URLs are not exploitable through this path.
  • Where user-influenced URLs do reach mutating calls, apply the advisory workaround at the interceptor or call site: parse with new URL(url, window.location.origin) and reject unless parsedUrl.origin === window.location.origin.

P2 (within 72 hours)

  • Upgrade to @angular/common 20.3.34, or to 21.0.3 / any 22.x release where the application can move. Rebuild and redeploy; this is a client-side library, so the fix only takes effect once the new bundle is served.
  • Review CORS configuration on any origin the application can be induced to call. The leak requires the attacker's server to accept the request and the X-XSRF-TOKEN custom header via CORS; a restrictive Access-Control-Allow-Headers on internal APIs does not help here because the receiving server is the attacker's, but auditing which third-party origins the application is permitted to call narrows the exposure.
  • If the application also runs Angular SSR, check @angular/platform-server against the patch versions in GHSA-f6mr-pjwc-34m4, GHSA-xrxm-cp7j-8xf6 and GHSA-rfh7-fxqc-q52v and upgrade in the same change window.

P3 (within 7 days)

  • Add a lint or build-time check that rejects HttpClient mutating calls whose URL argument is not a literal or a value passed through the origin-comparison helper, so the pattern does not return in future code.
  • Where the application sets a custom cookieName or headerName for XSRF, confirm the token is not additionally exposed through a response header readable by script.

5. Indicators of compromise

No indicators of compromise available in the source material. The advisory describes a code-level defect and gives example hostnames (evil.example, attacker.example) that are placeholders, not infrastructure. There are no hashes, domains, IP addresses or file paths to publish.

The observable behaviours below are derived from the advisory's description of the flaw and are single-sourced to it; treat them as detection hypotheses to validate against your own application, not as confirmed attack telemetry.

Behavioural indicators

behaviour where to observe confidence
Outbound POST/PUT/DELETE/PATCH from the browser to an origin outside the application's allowlist, carrying an X-XSRF-TOKEN header Browser network telemetry, CSP connect-src violation reports, reverse-proxy or egress logs where the client is instrumented Medium (single-sourced)
Request URLs containing backslashes, leading C0 control characters or spaces, or embedded tab/newline/CR characters in the path or scheme Web application firewall and proxy request logs, client-side error reporting Medium (single-sourced)
CORS preflight from the application origin to an unexpected host requesting the X-XSRF-TOKEN header Server logs on the receiving host, if within your estate; otherwise not observable Low (single-sourced)

6. Detection

The source material contains no file artefacts, command-line flags, mutexes, registry keys or hard-coded values belonging to an attacker tool. The only concrete strings are URL forms and the interceptor's regular expression, which are properties of the vulnerable library rather than of an attack payload. A YARA rule built on those would detect the framework, not the threat, so none is emitted.

A Sigma rule is possible against web logs, keyed on the URL forms the advisory lists. The strings are exact as they appear in the advisory.

title: Angular XSRF interceptor URL parser differential attempt
id: 8f2c1a44-6b7e-4d21-9c3a-angularxsrf01
status: experimental
description: Detects HTTP request targets containing the URL forms that bypass Angular xsrfInterceptorFn origin checks (CVE-2025-66035 incomplete fix). Single-sourced to GHSA-jfgx-762w-99vr; validate against your application before alerting.
author: Adverse Trace
date: 2026-10-20
references:

  - https://github.com/advisories/GHSA-jfgx-762w-99vr
logsource:
  category: webserver
detection:
  selection_backslash:
    cs-uri-stem|contains:

      - '/\'
      - '\\'
      - '\/'
  selection_control:
    cs-uri-stem|re: '^[\x00-\x20]|[\x00-\x20]$'
  selection_whitespace:
    cs-uri-stem|contains:

      - '/\t/'
      - '/\n/'
      - '/\r/'
  selection_scheme:
    cs-uri-stem|contains:

      - 'htt\tps://'
      - 'https:\\'
      - 'https:/\'
  condition: 1 of selection_*
falsepositives:

  - Legitimate applications that encode backslashes or control characters in path segments
  - Automated scanners and fuzzers
level: medium

The rule fires on request targets, so it will catch the attempt at the point the request leaves the client or reaches a proxy you control. It will not fire on the attacker's receiving server, which is outside your visibility.

CVE assessment

1 referenced CVE

CVE CVSS Exploited EPSS Summary
CVE-2025-66035 7.7 High — 1% Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other langua…

7. Sources

  • GitHub Security Advisories, @angular/common: XSRF Token Leakage via URL Parsing Discrepancy in Angular HTTP Client (Incomplete fix for CVE-2025-66035), GHSA-jfgx-762w-99vr, published 2026-10-20. https://github.com/advisories/GHSA-jfgx-762w-99vr
  • GitHub Security Advisories, Angular: SSRF and Cross-Origin Credential Disclosure via URL Resolution Discrepancy in SSR, GHSA-f6mr-pjwc-34m4. https://github.com/advisories/GHSA-f6mr-pjwc-34m4
  • GitHub Security Advisories, @angular/platform-server: URL Parser Differential leading to SSRF Allowlist Bypass, GHSA-xrxm-cp7j-8xf6. https://github.com/advisories/GHSA-xrxm-cp7j-8xf6
  • GitHub Security Advisories, @angular/platform-server: SSRF via Hostname Hijacking, GHSA-rfh7-fxqc-q52v. https://github.com/advisories/GHSA-rfh7-fxqc-q52v
  • Angular pull request #65683, replacement of the absolute-URL regular expression with a WHATWG origin comparison. https://github.com/angular/angular/pull/65683

8. Adverse Trace position

Adverse Trace assesses CVE-2025-66035 at CVSS 7.7 HIGH, not in CISA KEV, EPSS 1%. The severity is real but the exploitation path is narrow: it requires an application that passes user-influenced URLs into mutating HttpClient calls, and the advisory records no in-the-wild use. Client impact concentrates in firms running Angular 20.3.x LTS below 20.3.34 with dynamic request URLs, where a leaked XSRF token converts into forged state-changing requests against authenticated sessions; firms on 21.0.3 or later and 22.x are not exposed to this variant. The related SSR advisories are separate defects and should be triaged on their own patch versions. We will track the 20.3.x LTS branch for any further incomplete-fix advisories, and we will re-issue this note if a public exploit or KEV listing appears. Clients who need help identifying affected applications across their estate should contact their Adverse Trace handler to scope a dependency review.


Read the original source →

Published via PulseTrace — Adverse Trace threat intelligence.

Post this to LinkedIn
Formatting is converted automatically — headings, bullets, a link back & hashtags. Paste straight in.
J
Jeff Davies