### 漏洞概述 该漏洞涉及在Zalo平台中,Webhook的replay deduplication(重放去重)功能未能正确隔离不同认证目标(authenticated target)。这可能导致攻击者通过构造特定的请求,绕过安全机制,实现非预期的行为。 ### 影响范围 - **受影响组件**:Zalo平台的Webhook处理逻辑。 - **潜在风险**:攻击者可能利用此漏洞进行重放攻击,导致数据泄露或系统被恶意操控。 ### 修复方案 1. **代码修改**: - 在`monitor.webhook.ts`文件中,对`isReplayEvent`函数进行了修改,确保每个认证目标的重放去重逻辑是独立的。 - 具体修改包括: - 使用`$update.event_name`和`$update.message_id`作为键值,确保不同目标的事件不会相互干扰。 - 在`handleZaloWebhookRequest`函数中,增加了对`isReplayEvent`的检查,确保只有合法的重放事件才会被处理。 2. **测试用例**: - 添加了新的测试用例`"handleZaloWebhookRequest"`,验证了不同认证目标的重放去重逻辑是否正确隔离。 - 测试用例中创建了两个不同的目标(`targetA`和`targetB`),并分别发送了相同的payload,确保它们的重放去重逻辑互不影响。 ### POC代码 ```typescript it("keeps replay dedupe isolated per authenticated target", async () => { const simA = vi.fn(); const simB = vi.fn(); const unregisterA = registerTarget({ path: "/hook-replay-scope", secret: "secret-a", statusSim: simA, }); const unregisterB = registerTarget({ path: "/hook-replay-scope", secret: "secret-b", statusSim: simB, account: { ...DEFAULT_ACCOUNT, accountId: "work", }, }); const payload = createTextUpdate({ messageId: "msg-replay-scope-1", userId: "123", userName: "", chatId: "123", text: "hello", }); await withServer(webhookRequestHandler, async (baseUrl) => { const first = await fetch(`${baseUrl}/hook-replay-scope`, { method: "POST", headers: { "x-bot-api-secret-token": "secret-a", "content-type": "application/json", }, body: JSON.stringify(payload), }); const second = await fetch(`${baseUrl}/hook-replay-scope`, { method: "POST", headers: { "x-bot-api-secret-token": "secret-b", "content-type": "application/json", }, body: JSON.stringify(payload), }); expect(first.status).toBe(200); expect(second.status).toBe(200); }); expect(simA).toHaveBeenCalledTimes(1); expect(simB).toHaveBeenCalledTimes(1); }); ``` ### 总结 该漏洞的修复确保了Zalo平台Webhook的重放去重功能能够正确隔离不同认证目标,从而防止潜在的安全风险。