# 漏洞总结 ## 漏洞概述 该漏洞涉及Zalo webhook的缓存键设计问题,导致跨账户缓存污染。具体表现为:当不同账户的path/account值在冒号连接键中发生冲突时,可能导致事件被错误地去重,从而丢失重要信息。 ## 影响范围 - **受影响组件**:Zalo webhook模块 - **影响场景**:多账户部署环境下,由于缓存键设计不当,可能导致不同账户的事件被错误地去重。 - **潜在风险**:重要事件可能被忽略,影响业务逻辑的正常运行。 ## 修复方案 1. **更新缓存键设计**:将缓存键从简单的path/account组合改为更复杂的结构,确保不同账户的事件不会发生冲突。 2. **代码修改**: - 修改`buildReplayEventCacheKey`函数,增加对`target.account.accountId`、`update.event_name`、`childId`、`senderId`和`messageId`的考虑。 - 修改`isReplayEvent`函数,使用新的缓存键进行事件去重检查。 ## POC代码 ```typescript // 修改后的buildReplayEventCacheKey函数 function buildReplayEventCacheKey( target: ZaloWebhookTarget, update: ZaloUpdate, messageId: string ): string { const chatId = update.message?.chat?.id ?? ""; const senderId = update.message?.from?.id ?? ""; return JSON.stringify([ target.path, target.account.accountId, update.event_name, chatId, senderId, messageId ].join(":")); } // 修改后的isReplayEvent函数 function isReplayEvent( target: ZaloWebhookTarget, update: ZaloUpdate, nowMs: number ): boolean { const messageId = update.message?.message_id; if (!messageId) { return false; } const chatId = update.message?.chat?.id ?? ""; const senderId = update.message?.from?.id ?? ""; // Scope replay dedupe to the authenticated target and the message origin so // reused message ids in other chats or from other senders do not collide. const key = [ target.path, target.account.accountId, update.event_name, chatId, senderId, messageId, "" ].join(":"); const key = buildReplayEventCacheKey(target, update, messageId); return recentWebhookEvents.check(key, nowMs); } ``` ## 其他信息 - **提交者**:pgondhi987和jacobtomlinson - **提交时间**:last month - **相关Issue**:#59387