mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-07-26 18:55:40 +00:00
security(p2p): fix withdrawal BOLA, financial RLS exposure, admin dispute escrow
Critical/high audit remediation on the custodial P2P ledger. Auth model is wallet-based; identity (citizen/visa) is cryptographically bound to a wallet (People Chain tiki.citizenNft / active p2p_visa), which enables a correct fix. - Withdrawal BOLA (CRITICAL): process-withdraw now requires a wallet-SIGNED challenge; server verifies signature (raw + <Bytes> forms), asserts the signer OWNS the identity, consumes a single-use nonce (replay), and derives user_id server-side — the client-supplied user_id is ignored. process-withdrawal (batch) now requires the service-role key (was: any bearer, incl. public anon key). request_withdraw is REVOKEd from anon/authenticated + service-role guarded. - Financial RLS (HIGH): drop the blanket USING(true) SELECT on user_internal_balances, p2p_balance_transactions, p2p_deposit_withdraw_requests; lock p2p_user_payment_methods (IBAN PII) + p2p_fiat_disputes UPDATE to service_role; legitimate reads move behind scoped SECURITY DEFINER RPCs. - Deposit integrity: verify-deposit now binds the on-chain sender to identity ownership before crediting. - Admin dispute (CRITICAL fund-logic): DisputeResolutionPanel relabeled trades without moving escrow. New admin-signed resolve-dispute function + admin_resolve_dispute RPC moves escrow (release/refund/split) atomically with correct accounting (avoids the double-count in the legacy resolve_p2p_dispute). Client isAdmin documented as cosmetic. DEPLOY RUNBOOK (gated; owner runs): 1) apply migrations 20260225/20260725* in order; 2) deploy edge functions process-withdraw, process-withdrawal, verify-deposit, resolve-dispute; 3) set edge secrets PEOPLE_RPC_ENDPOINT (+ optional ADMIN_WALLETS); 4) ship frontend. Migrations + functions + frontend must go together or the app breaks. KNOWN RESIDUAL (Round 2 — as severe as the withdrawal BOLA): release_/lock_/refund_ escrow_internal still have PUBLIC EXECUTE and the client calls release_escrow_internal directly with the anon key from confirmPaymentReceived -> an anon caller can drain any victim's LOCKED balance. Fix = a wallet-signed confirm-payment edge function (same pattern as withdrawals) before revoking PUBLIC execute. Not yet fixed.
This commit is contained in:
@@ -115,6 +115,17 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
|
||||
|
||||
const checkAdminStatus = useCallback(async () => {
|
||||
// ============================================================
|
||||
// COSMETIC ONLY — NOT an authorization boundary.
|
||||
// ------------------------------------------------------------
|
||||
// This flag is derived from a localStorage wallet value and can be trivially
|
||||
// forged in DevTools. It ONLY controls whether admin UI is shown. Every
|
||||
// privileged operation MUST be verified server-side:
|
||||
// - Dispute claim/resolve -> `resolve-dispute` edge function verifies a
|
||||
// wallet SIGNATURE against the server-side admin wallet set before doing
|
||||
// anything (see supabase/functions/resolve-dispute + _shared/identity-auth).
|
||||
// Do NOT add fund-moving or state-changing logic gated solely on isAdmin.
|
||||
// ============================================================
|
||||
// Admin wallet whitelist (blockchain-based auth)
|
||||
const ADMIN_WALLETS = [
|
||||
'5CyuFfbF95rzBxru7c9yEsX4XmQXUxpLUcbj9RLg9K1cGiiF', // Founder
|
||||
|
||||
Reference in New Issue
Block a user