"Never trust the client. Never trust a supplied relationship. Never trust a supplied price. Never trust an authorization claim. Verify every security-critical invariant at the enforcement layer."
- We assume all browser environments (React state,
localStorage, client memory, DevTools) are fully compromised or attacker-controlled. - Prices, user roles, wallet identities, and permissions are never established by client declaration.
- Every economic transaction and permission claim is verified either:
- On-chain via the Solana Virtual Machine (SVM) program constraints; or
- Server-side via cryptographic signature verification against domain-bound nonces.
| Layer | Responsibilities | Security Enforcement |
|---|---|---|
| On-Chain (SVM Anchor Program) | - Product ownership and pricing - Automated 5% fee split routing - Creator proceeds delivery - Unique purchase receipt PDA creation - Emergency pause and governance |
- Strict Anchor account constraints - Deterministic PDAs ( platform, product, receipt)- Checked integer arithmetic ( checked_add, checked_mul, checked_div)- Invariant: creator + treasury == total |
Server / API Layer (Next.js) |
- Cryptographic wallet challenge issuance and verification - Multimodal AI vision screening ( /api/shield/scan)- Sliding-window rate limiting - Anti-SSRF URL filtering - Admin-only platform operations |
- Ed25519 signature checks (SIWS standard) - Replay attack prevention via single-use nonces - Cloud metadata ( 169.254.169.254) and private IP rejection- Payload size limits (5MB) |
| Client / Creator SDK Layer | - Storefront presentation - Nightly wallet connector - Ephemeral RAM transient processing |
- Input sanitization (XSS defense) - Sandbox mocks for devnet testing - Zero persistent storage of sensitive biometrics |
For every on-chain economic transfer:
- Single Source of Truth: The fee rate is dynamically retrieved from
PlatformState.fee_bps. No constants are duplicated across instruction handlers. - Bounded Fees: Maximum fee is hard-capped at 25.00% (
MAX_FEE_BPS = 2_500). - Mathematical Safety: Checked integer arithmetic prevents overflow and underflow across all amounts from 1 lamport to maximum safe u64.
- Never Trust Client Price:
purchase_productreadsproduct.price_lamportsstrictly from the on-chainProductaccount PDA derived from[b"product", creator, product_id]. - Creator Authorization: Only the authorized creator signer can create or modify products.
- Anti-Wash Trading Protection: The contract strictly disallows self-tipping (
tipper != creator) and self-purchases (buyer != creator) to prevent artificial metric inflation and fake transaction volume.
- Two-Step Admin Transfer: Ownership transfers require initiation by current admin (
transfer_admin), followed by explicit acceptance signature from the pending admin (accept_admin). - Emergency Circuit Breaker: The platform can be paused by governance (
pause_platform) to freeze all tips and purchases during security incidents while administrative recovery functions operate. - Typed Account Validation: All creator and treasury destinations use typed
SystemAccount<'info>withhas_oneconstraints to eliminate account substitution attacks.
- Fail-Closed Secret Enforcement:
SESSION_SECRETmust be set with at least 32 characters in all environments; missing or short secrets trigger immediate fail-closed shutdown. - Versioned HMAC Tokens: Stateless tamper-evident tokens using
v1.<payloadBase64Url>.<signatureBase64Url>format signed with HMAC-SHA256 and constant-timecrypto.timingSafeEqualcomparison. - Distributed State Coordination:
- Single-Instance / Local Dev: High-performance in-memory Maps with sliding-window pruning, capacity bounds (
MAX_ACTIVE_CHALLENGES = 10,000), and automatic expiration cleanup. - Multi-Instance / Serverless (Vercel): Zero-dependency REST adapter supporting Upstash Redis / Vercel KV for atomic single-use nonce consumption (
GETDEL), cross-instance session revocation blocklists, and global rate limiting.
- Single-Instance / Local Dev: High-performance in-memory Maps with sliding-window pruning, capacity bounds (
Permanent security regression tests are located under tests/security/:
fee-invariant.test.mjs: Fuzzes 1,000 randomized amounts and boundary edge cases (1 lamport, 19 lamports, 100, 10,000, 1M COOK) confirming 100% preservation of the fee invariant.sanitize.test.mjs: Tests XSS payloads and SSRF vectors (cloud metadata, loopback, private IPv4 blocks).wallet-auth.test.mjs: Tests Ed25519 signature verification, nonce expiry, address mismatch rejection, and anti-replay nonce consumption.rate-limiter.test.mjs: Tests sliding-window quota enforcement and key isolation under simulated DoS traffic.session.test.mjs: Tests v1 token generation, tampering detection, fail-closed secrets, expiration, and authenticated revocation.contract-invariants.test.mjs: Tests anti-wash self-tipping rejection, self-purchase wash trading rejection, CEI ordering, and destination constraints.distributed-store.test.mjs: Tests atomicGETDELnonce consumption, distributed TTL pruning, rate limiting increments, and REST protocol conformity.authorization.test.mjs: Tests multi-factor adulthood verification, role hierarchy, under-25 safeguards, and server-side feed shielding.trust-wallet-signer.test.mjs: Tests private key formats, SIWS challenge verification, and zero-leak platform administration controls.
Execute all suites locally with:
npm testIf you discover a security vulnerability, please do NOT create a public issue.
- Private Vulnerability Reporting: Enabled on this repository. Visit Security Advisories to submit a confidential report.
- Our security response team will review submissions promptly.