SplitSafe Pay — Launch readiness review
Solana group expense and settlement app with AI-powered receipt scanning, Wallet Adapter, and Supabase backend. Generated by LaunchGuard Solana on 4/29/2025, 2:25:01 PM.
Risky — fix critical issues before mainnet launch.
Web3 risk radar
Per-category readiness across the Solana attack surface.
Mainnet readiness
Risky 58 / 100
Risky. Resolve the blocker list before mainnet — Shannon-confirmed exploits are present.
- P0CriticalShannon confirmedSupabase service role key pattern detected in frontend bundle
- P0CriticalNot applicableMissing signer validation in Anchor instruction
- P0HighShannon confirmedAPI route allows expense update without workspace authorization
- P0HighShannon confirmedWallet ownership checked only in frontend
- P1HighNot applicableTransaction amount trusted from client input
- P2MediumShannon confirmedNo rate limit on AI receipt endpoint
- P2MediumNeeds reviewVulnerable next dependency in lockfile
- P2MediumNeeds reviewMissing security headers in Vercel/Next.js config
- …and 3 more
- P3LowShannon confirmedError messages reveal internal database details
Resolve every P0 in the Blockers list, then re-run the Enterprise Full Audit with Shannon authorized.
Top findings
12 normalizedSupabase service role key pattern detected in frontend bundle
TruffleHog actively verified that a Supabase service role key is reachable from the browser bundle. The actual key is not displayed by LaunchGuard. Rotate immediately and move it to a server-only env var.
Missing signer validation in Anchor instruction
An attacker could call this on-chain instruction without proving they are the actual member, letting them settle expenses on behalf of someone else.
API route allows expense update without workspace authorization
Any authenticated user can update any expense, including expenses from other workspaces. Shannon validated this live against the staging URL.
Wallet ownership checked only in frontend
The app verifies wallet ownership in the browser but not on the server. Anyone who skips the UI can pretend to own a wallet they don't.
Transaction amount trusted from client input
The amount paid is taken from the user's request body without verifying against the database expense. A modified request can underpay or overpay.
No rate limit on AI receipt endpoint
Attackers can spam the AI receipt endpoint and run up your provider bill. Shannon issued a small authorized burst and the endpoint accepted every request without throttling.
Engine confidence matrix
Rows are findings, columns are engines. Green check = verified live, dot = detected, dash = not applicable.
| Finding | LG | SG | NJS | TH | GL | OSV | TRV | DS | SH |
|---|---|---|---|---|---|---|---|---|---|
Supabase service role key pattern detected in frontend bundle app/lib/supabase-public.ts | |||||||||
Missing signer validation in Anchor instruction programs/splitsafe_pay/src/instructions/settle.rs | |||||||||
API route allows expense update without workspace authorization app/api/expenses/[id]/route.ts | |||||||||
Wallet ownership checked only in frontend app/api/groups/[groupId]/members/route.ts | |||||||||
Transaction amount trusted from client input app/api/expenses/settle/route.ts | |||||||||
No rate limit on AI receipt endpoint app/api/ai/scan-receipt/route.ts | |||||||||
Vulnerable next dependency in lockfile pnpm-lock.yaml | |||||||||
Missing security headers in Vercel/Next.js config next.config.mjs | |||||||||
Supabase RLS missing on expenses table supabase/migrations/0001_init.sql | |||||||||
Error messages reveal internal database details app/api/expenses/route.ts | |||||||||
Dockerfile runs container as root user Dockerfile | |||||||||
SSRF: user-controlled URL passed to fetch / http.request app/api/proxy/route.ts |
App map
Solana group expense and settlement app
- Sign in with email + connect Solana wallet
- Create a group and invite members
- Add expense (manual or via AI receipt scan)
- Settle balances on-chain via SPL token transfers
- Export monthly statements
- Solana Wallet Adapter (Phantom, Backpack, Solflare)
- Sign-in with Solana (SIWS) for session establishment
- Custodial signer for batched settlements
- POST /api/groups
- PATCH /api/expenses/[id]
- POST /api/expenses/settle
- POST /api/ai/scan-receipt
- GET /api/reports/monthly
- Frontend bundle (verified Supabase service-role key exposure)
- settle_expense Anchor instruction (signer + amount)
- PATCH /api/expenses/[id] (cross-tenant)
- POST /api/ai/scan-receipt (cost abuse)
Threat model
SplitSafe Pay lets small groups split expenses, scan receipts with AI, and settle balances on Solana through a shared on-chain ledger.
- Member wallet pubkeys and signatures
- Group expense data
- Solana program authority
- Custodial signer keypair (server-only)
- Supabase service role key (server-only)
- Cross-tenant tampering: An attacker uses a valid session in workspace A to read or modify rows from workspace B by guessing IDs.
- AI receipt cost abuse: An abuser hammers the AI receipt endpoint to drive up provider cost or trigger denial-of-wallet.
- Settlement amount manipulation: A user submits a smaller amount in the settlement request than the original expense.
- Service-role key abuse: A leaked Supabase service-role key gives an attacker full read/write to every row, bypassing RLS.
- Rotate the Supabase service-role key and move it to server-only env
- Add Anchor Signer + has_one constraints across all financial instructions
- Enforce workspace_id checks in every API route plus matching Supabase RLS policies
- Implement signed-nonce wallet ownership verification
- Add Upstash/Redis rate limiter on AI endpoints with per-workspace daily quotas
- Add canonical security headers (HSTS, X-Frame-Options, X-Content-Type-Options)
