Skip to content

CSRF Token Protection for Mutating API Routes #560

Description

@Kingsman-99

Description

All POST, PUT, PATCH, and DELETE API routes currently accept requests without verifying that they originate from the app's own frontend, making them vulnerable to cross-site request forgery. Adding CSRF token validation closes this attack vector without breaking the existing wallet-based authentication flow.

Technical Context

A CSRF token utility at src/lib/csrf.ts generates and validates tokens using the crypto Web API (crypto.randomUUID + HMAC-SHA256 with a CSRF_SECRET environment variable). A server-side helper src/lib/middleware/csrfMiddleware.ts validates the X-CSRF-Token header on all mutating routes (e.g., src/app/api/invoices/route.ts, src/app/api/recipients/route.ts). A client-side hook src/hooks/useCsrfToken.ts fetches the token from GET /api/csrf and injects it into all fetch calls via a centralized src/lib/apiClient.ts wrapper.

Acceptance Criteria

  • All mutating API routes return 403 Forbidden when the X-CSRF-Token header is absent or invalid
  • GET /api/csrf returns a fresh signed token that is valid for exactly 60 minutes
  • The useCsrfToken hook automatically refreshes the token before expiry and retries the queued request transparently
  • The CSRF secret is loaded from process.env.CSRF_SECRET; the app fails to start at build time if the variable is missing
  • Wallet-connect flows and read-only GET routes are unaffected and require no token
  • All CI checks (npm test, npm run build, ESLint/TypeScript) pass and the branch has no merge conflicts

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions