From 113a97ed28883a0ef4a4fc39b420fe1d7ab3931a Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 19 May 2026 12:26:57 -0300 Subject: [PATCH 1/2] security: prevent cross-instance auth bypass via query/body override (#2435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The auth guard in src/api/guards/auth.guard.ts validates instance ownership using req.params.instanceName. The abstract router then merged req.query (and, on /instance/create, req.body) into the instance object via Object.assign — which silently overwrote the already-authenticated instanceName. An attacker with one valid token could send: GET /chat/findMessages/MY_INSTANCE?instanceName=VICTIM_INSTANCE Auth passed for MY_INSTANCE, but dataValidate() then replaced the instance with VICTIM_INSTANCE before execute() ran — giving the caller full access to read/send messages, modify settings, and delete other tenants' instances. CWE-639: Authorization Bypass Through User-Controlled Key Fix: introduce sanitizeUntrustedInput() that strips PROTECTED_INSTANCE_FIELDS (instanceName, instanceId) from any untrusted source before merging into the instance object. Logs a warning on attempts so abuse is auditable. Closes #2435 Reported by @lighthousekeeper1212 via static analysis. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/api/abstract/abstract.router.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/api/abstract/abstract.router.ts b/src/api/abstract/abstract.router.ts index e8449a8c8a..2a64296ded 100644 --- a/src/api/abstract/abstract.router.ts +++ b/src/api/abstract/abstract.router.ts @@ -17,6 +17,21 @@ type DataValidate = { const logger = new Logger('Validate'); +const PROTECTED_INSTANCE_FIELDS = ['instanceName', 'instanceId'] as const; + +function sanitizeUntrustedInput(source: Record | undefined): Record { + if (!source || typeof source !== 'object') return {}; + const sanitized: Record = {}; + for (const [key, value] of Object.entries(source)) { + if ((PROTECTED_INSTANCE_FIELDS as readonly string[]).includes(key)) { + logger.warn(`Ignoring attempt to override protected field "${key}" via untrusted input`); + continue; + } + sanitized[key] = value; + } + return sanitized; +} + export abstract class RouterBroker { constructor() {} public routerPath(path: string, param = true) { @@ -34,11 +49,11 @@ export abstract class RouterBroker { const instance = request.params as unknown as InstanceDto; if (request?.query && Object.keys(request.query).length > 0) { - Object.assign(instance, request.query); + Object.assign(instance, sanitizeUntrustedInput(request.query as Record)); } if (request.originalUrl.includes('/instance/create')) { - Object.assign(instance, body); + Object.assign(instance, sanitizeUntrustedInput(body)); } Object.assign(ref, body); From 8ed2b153f6a0b7ac98158f120452f5ebee7e4035 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Tue, 19 May 2026 12:27:54 -0300 Subject: [PATCH 2/2] chore(lint): remove extra blank line introduced by recent merge Pre-push lint flagged whatsapp.baileys.service.ts:531 (double blank line after the stream:error 515 fix merged via #2509). Trivial prettier fix. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../integrations/channel/whatsapp/whatsapp.baileys.service.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts index 788ebdd907..e042629994 100644 --- a/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts +++ b/src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts @@ -528,7 +528,6 @@ export class BaileysStartupService extends ChannelStartupService { instanceName: this.instance.name, }); - if (shouldReconnect) { // Add 3 second delay before reconnection to prevent rapid reconnection loops this.logger.info('Reconnecting in 3 seconds...');