enforce server-side, on-chain-verified credit issuance (unlimited-cre… - #56
enforce server-side, on-chain-verified credit issuance (unlimited-cre…#56mertcano wants to merge 1 commit into
Conversation
…dit mint)
A critical vulnerability in the credit top-up path where the server previously trusted client-supplied credit and USDC amounts without on-chain verification.
**🚨 Vulnerabilities & Anti-Patterns Remediated:**
* **Business Logic / Broken Access Control — Unlimited Credit Minting (CRITICAL):**
Previously, `POST /api/transactions` stored `credit_amount` straight from the request body. Combined with the Circle webhook granting exactly `transaction.credit_amount` upon confirmation, an authenticated user could mint an unlimited number of credits for the cost of a single $0.01 USDC transfer.
**Fix:** The endpoint now ignores client-supplied `credits` and `usdcAmount`. Issuance is calculated strictly server-side using the hardcoded `EXCHANGE_RATE_USDC_PER_CREDIT`.
* **Missing On-Chain Settlement Verification (CRITICAL):**
The server recorded a payment purely based on the client's payload.
**Fix:** Integrated `viem` to fetch the transaction receipt by `txHash` via a server RPC. The transaction is verified to ensure it represents a successful USDC transfer to the correct admin wallet from the authenticated user's wallet before any database insertion occurs.
* **Sensitive Error Disclosure (MEDIUM):**
Raw database and Row-Level-Security (RLS) errors (e.g., `insertError.message`, `insertError.code`, `RLS_BLOCK`) were previously passed directly to the client via 500 responses.
**Fix:** Detailed error logs are now isolated to the server console. The client receives generic, opaque error codes (e.g., "Insert failed" or "Server error").
**Key Code Changes:**
* `app/api/transactions/route.ts`: Completely refactored the `POST` handler to perform on-chain receipt validation, decode USDC `Transfer` event logs, and strictly derive credit allocations on the backend.
|
Direction is good (server-derived credits + receipt check), but as written the verification is still attacker-controlled in two places that defeat the CRITICAL claim. 1. Client-supplied
|
A critical vulnerability in the credit top-up path where the server previously trusted client-supplied credit and USDC amounts without on-chain verification.
** Vulnerabilities & Anti-Patterns Remediated:**
Business Logic / Broken Access Control — Unlimited Credit Minting (CRITICAL):
Previously,
POST /api/transactionsstoredcredit_amountstraight from the request body. Combined with the Circle webhook granting exactlytransaction.credit_amountupon confirmation, an authenticated user could mint an unlimited number of credits for the cost of a single $0.01 USDC transfer.Fix: The endpoint now ignores client-supplied
creditsandusdcAmount. Issuance is calculated strictly server-side using the hardcodedEXCHANGE_RATE_USDC_PER_CREDIT.Missing On-Chain Settlement Verification (CRITICAL):
The server recorded a payment purely based on the client's payload.
Fix: Integrated
viemto fetch the transaction receipt bytxHashvia a server RPC. The transaction is verified to ensure it represents a successful USDC transfer to the correct admin wallet from the authenticated user's wallet before any database insertion occurs.Sensitive Error Disclosure (MEDIUM):
Raw database and Row-Level-Security (RLS) errors (e.g.,
insertError.message,insertError.code,RLS_BLOCK) were previously passed directly to the client via 500 responses.Fix: Detailed error logs are now isolated to the server console. The client receives generic, opaque error codes (e.g., "Insert failed" or "Server error").
Key Code Changes:
app/api/transactions/route.ts: Completely refactored thePOSThandler to perform on-chain receipt validation, decode USDCTransferevent logs, and strictly derive credit allocations on the backend.