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 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-03-07 09:41:09 -05:00
commit 46f12e5629

View file

@ -248,22 +248,25 @@ ipcMain.handle('hal:disable-validator', () => {
}) })
ipcMain.handle('hal:stack-bill', () => { ipcMain.handle('hal:stack-bill', () => {
if (halInstance) { if (!halInstance) return
const denomination = pendingBillDenomination if (pendingBillDenomination === null) {
pendingBillDenomination = null console.warn('[Electron] hal:stack-bill called with no bill in escrow — ignoring')
halInstance.stackBill() return
// Notify renderer that the bill was accepted
if (denomination !== null) {
mainWindow?.webContents.send('hal:bill-inserted', denomination)
}
} }
const denomination = pendingBillDenomination
pendingBillDenomination = null
halInstance.stackBill()
mainWindow?.webContents.send('hal:bill-inserted', denomination)
}) })
ipcMain.handle('hal:reject-bill', () => { ipcMain.handle('hal:reject-bill', () => {
if (halInstance) { if (!halInstance) return
pendingBillDenomination = null if (pendingBillDenomination === null) {
halInstance.rejectBill() console.warn('[Electron] hal:reject-bill called with no bill in escrow — ignoring')
return
} }
pendingBillDenomination = null
halInstance.rejectBill()
}) })
ipcMain.handle('hal:get-inventory', () => { ipcMain.handle('hal:get-inventory', () => {