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