Files
pwap/web
pezkuwichain 25ed29edcb security(p2p): freeze trade/offer fund-routing columns + atomic release (2 verify-found bypasses) + tests
A bounded adversarial re-verification of the new fund-custody auth found two real
bypasses that the fix rounds missed; both fixed here, plus executable proof.

- BYPASS #1 (CRITICAL, external): p2p_fiat_trades/p2p_fiat_offers kept USING(true)
  anon UPDATE, and confirm-payment / admin_resolve_dispute read the fund DESTINATION
  (buyer_id), amount and token straight from those rows. An anon attacker could
  `UPDATE p2p_fiat_trades SET buyer_id=<attacker>` so the honest seller's correctly-
  signed release paid the attacker. Fix: BEFORE UPDATE triggers freeze the fund-routing
  columns (offer_id, seller_id, buyer_id, crypto_amount, fiat_amount, price_per_unit,
  escrow_locked_amount on trades; seller_id, token, amount_crypto on offers) for any
  non-service-role writer — trigger-level, independent of RLS/grants; status/proof/chat
  stay open. (Corrects the earlier triage that dismissed these tables as non-custodial.)
- BYPASS #2 (double-release TOCTOU): confirm-payment checked status then released
  non-atomically, so two concurrent differently-nonced valid requests could both release
  and drain other buyers' escrow. Fix: atomic compare-and-swap of payment_sent->completed
  BEFORE the escrow move (loser gets 409; revert on release failure).
- Hardening: REVOKE EXECUTE on the dead legacy resolve_p2p_dispute mover from
  PUBLIC/anon/authenticated.
- Proof: 34 executable tests (Deno) — identity-auth unit tests (sr25519 sign/verify,
  challenge money-param binding, citizen/visa ownership, nonce single-use+concurrency,
  freshness) + per-handler authorization-flow tests (bad-sig/cross-id/wrong-state/replay,
  CAS double-release). All pass.
2026-07-25 02:44:02 -07:00
..