From 46f12e5629f52aac5b56f6b2e1fb0b83aee8d9ee Mon Sep 17 00:00:00 2001 From: Patrick Mulligan Date: Sat, 7 Mar 2026 09:41:09 -0500 Subject: [PATCH] security(H4): fix bill escrow race condition Guard hal:stack-bill and hal:reject-bill IPC handlers against being called when no bill is in escrow (pendingBillDenomination === null). Previously, rapid-fire calls could double-accept or misattribute bill denominations. Now the handlers silently ignore calls when no bill is pending, preventing the race. Co-Authored-By: Claude Opus 4.6 --- apps/machine/electron/main.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/apps/machine/electron/main.ts b/apps/machine/electron/main.ts index 51f8bbe..1b6c41e 100644 --- a/apps/machine/electron/main.ts +++ b/apps/machine/electron/main.ts @@ -248,22 +248,25 @@ ipcMain.handle('hal:disable-validator', () => { }) ipcMain.handle('hal:stack-bill', () => { - if (halInstance) { - const denomination = pendingBillDenomination - pendingBillDenomination = null - halInstance.stackBill() - // Notify renderer that the bill was accepted - if (denomination !== null) { - mainWindow?.webContents.send('hal:bill-inserted', denomination) - } + if (!halInstance) return + if (pendingBillDenomination === null) { + console.warn('[Electron] hal:stack-bill called with no bill in escrow — ignoring') + return } + const denomination = pendingBillDenomination + pendingBillDenomination = null + halInstance.stackBill() + mainWindow?.webContents.send('hal:bill-inserted', denomination) }) ipcMain.handle('hal:reject-bill', () => { - if (halInstance) { - pendingBillDenomination = null - halInstance.rejectBill() + if (!halInstance) return + if (pendingBillDenomination === null) { + console.warn('[Electron] hal:reject-bill called with no bill in escrow — ignoring') + return } + pendingBillDenomination = null + halInstance.rejectBill() }) ipcMain.handle('hal:get-inventory', () => {