From 0a43ad849d12029bd7ea971d434e3f9f0035fe6c Mon Sep 17 00:00:00 2001 From: Renato Alcara Date: Sun, 1 Mar 2026 17:10:57 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20normalize=20LID=E2=86=92PN=20in=20handle?= =?UTF-8?q?BadAck,=20media=20retry,=20and=20PDO=20recovery?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additional leak points found during final audit: - handleBadAck: key.remoteJid from ack stanza could be LID - messages.media-update: media retry key JIDs not normalized - CTWA PDO recovery: webMessageInfo.key from phone response not normalized Co-Authored-By: Claude Opus 4.6 --- src/Socket/messages-recv.ts | 5 ++++- src/Utils/process-message.ts | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Socket/messages-recv.ts b/src/Socket/messages-recv.ts index c097d88c..3474dd26 100644 --- a/src/Socket/messages-recv.ts +++ b/src/Socket/messages-recv.ts @@ -1645,6 +1645,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { break case 'mediaretry': const event = decodeMediaRetryNode(node) + // Normalize LID→PN in media retry key before emitting + await normalizeKeyLidToPn(event.key, signalRepository.lidMapping, logger) ev.emit('messages.media-update', [event]) break case 'encrypt': @@ -2734,7 +2736,8 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => { } const handleBadAck = async ({ attrs }: BinaryNode) => { - const key: WAMessageKey = { remoteJid: attrs.from, fromMe: true, id: attrs.id } + const resolvedFrom = await resolveLidToPn(attrs.from, signalRepository.lidMapping, logger) || attrs.from + const key: WAMessageKey = { remoteJid: resolvedFrom, fromMe: true, id: attrs.id } // WARNING: REFRAIN FROM ENABLING THIS FOR NOW. IT WILL CAUSE A LOOP // // current hypothesis is that if pash is sent in the ack diff --git a/src/Utils/process-message.ts b/src/Utils/process-message.ts index a2570111..19b95a2b 100644 --- a/src/Utils/process-message.ts +++ b/src/Utils/process-message.ts @@ -589,6 +589,12 @@ const processMessage = async ( 'CTWA: Successfully recovered message via placeholder resend' ) + // Normalize LID→PN in PDO-recovered message key before emitting + // eslint-disable-next-line max-depth + if (webMessageInfo.key && signalRepository) { + await normalizeKeyLidToPn(webMessageInfo.key as WAMessageKey, signalRepository.lidMapping, logger) + } + // wait till another upsert event is available, don't want it to be part of the PDO response message // TODO: parse through proper message handling utilities (to add relevant key fields) ev.emit('messages.upsert', {