Skip to content

CRITICAL: Confirmation endpoint has no wallet-scoping — any user can confirm any pending operation #95

@rz1989s

Description

@rz1989s

Description

POST /api/confirm/:id only checks if the confirmation ID exists in the pending map. It never checks whether the authenticated wallet is the one that initiated the fund-moving operation.

ULIDs are time-based and partially predictable. An attacker who knows or guesses a confirmation ID can confirm operations on behalf of another user.

File

packages/agent/src/routes/confirm.ts:19-34

The pending map stores { resolve, timer } but never stores the originating wallet. The requestConfirmation() function at line 41 does not accept a wallet parameter.

Fix

  1. Add wallet field to pending entry: { resolve, timer, wallet }
  2. Accept wallet in requestConfirmation(id, wallet, timeoutMs)
  3. Validate req.wallet === entry.wallet before resolving
const pending = new Map<string, { 
  resolve: (confirmed: boolean) => void
  timer: NodeJS.Timeout
  wallet: string  // <-- add this
}>()

// In handler:
if (entry.wallet !== (req as any).wallet) {
  res.status(403).json({ error: 'confirmation belongs to a different wallet' })
  return
}

Priority

CRITICAL — fund-moving operations confirmable by unauthorized wallet

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority-criticalMust fix before deadlinesecuritySecurity improvement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions