Skip to main content

Security

Payment Verification

Forlarge never trusts client-reported payments. Every transaction is verified independently on the server:
1

Buyer signs transaction

The buyer signs a USDC transfer in their wallet and broadcasts it to Injective.
2

Server-side verification

Forlarge’s servers query the Injective network to confirm:
  • Transaction exists and is finalized
  • Correct USDC amount was transferred
  • Payment was sent to the correct creator wallet address
  • Payout split matches the active fee policy for the environment
3

Download issued

Only after server-side verification passes does Forlarge issue a download token.

Injective Cosmos Verification

Forlarge queries the Injective LCD REST API. MsgSend bank messages are parsed to verify USDC denom and amount match the expected values. Both native USDC (CCTP via Noble IBC) and legacy Peggy USDC are accepted.

Injective EVM Verification

Forlarge calls eth_getTransactionReceipt via the Injective EVM JSON-RPC. The response logs are scanned for ERC-20 Transfer(from, to, amount) events on the USDC contract. The to address is verified against the creator’s inj1 address (converted from bech32 to EVM hex for comparison).

Download Security

  • Cryptographically random tokens — download URLs use 32-character nanoid tokens
  • Time-limited — tokens expire after 24 hours
  • Use-limited — each token allows up to 5 downloads
  • Server-side validation — every download request is checked against the purchase record
  • No direct file URLs — product files are never publicly accessible without a valid token

Authentication

Email + Password

  • Minimum 8-character password enforced at signup (with a strength indicator)
  • Passwords hashed via Supabase Auth (bcrypt)
  • Email confirmation required

Google OAuth

  • Full server-side OAuth flow with canonical base URL resolution
  • CSRF protection via state tokens
  • Tokens exchanged server-side, never exposed in the browser

Wallet-Based Login

  • Nonce-based challenge/response flow for Injective wallets (Cosmos and EVM)
  • Public key derivation verified against the claimed inj1 address — prevents cross-address attacks
  • Nonces are single-use, expire after 5 minutes, and are deleted immediately after verification
  • Rate limited: 20 requests/IP/min and 6 requests/wallet/min on the nonce endpoint

Invite Code Security

Invite codes are claimed atomically via the activate_account_with_invite DB function — a single transaction that validates, claims, and activates in one operation. This prevents race conditions where two concurrent signups could claim the same code. Rate limiting: 10 invite code validation attempts per hour per IP and per user.

Access Control

Invite-Gated Registration

New creator accounts on forlarge.app require a valid invite code. access_granted is set only after atomic invite validation. The testnet deployment (test.forlarge.app) is login-only — no invite required, access is granted by host detection.

Row-Level Security (RLS)

Supabase RLS policies enforce:
  • Users can only modify their own profiles and products
  • Buyers can only read their own transactions (buyer_user_id match)
  • Payment records are immutable after creation
  • Admin endpoints require server-side admin role verification
  • Wallet nonce table is service-role only — no client access

Guest → Account Linking

When a buyer who purchased without an account later signs up with the same email, a DB trigger automatically sets buyer_user_id on their past transactions. No manual steps required.

Infrastructure Security

  • HTTPS everywhere — all traffic encrypted in transit
  • Supabase — database and auth on SOC 2 Type II compliant infrastructure
  • Secrets as env vars — no API keys or secrets in code
  • Service role key server-side only — never exposed to the browser
  • CRON_SECRET — all cron endpoints require a Bearer token header
  • SET search_path = public — all SECURITY DEFINER functions hardened against search path injection

Reporting Vulnerabilities

Please report security issues responsibly by contacting us directly. Do not disclose vulnerabilities publicly before they are resolved.