Skip to content

CSRF Protection for Registration Forms

Why We Added This

Without CSRF protection, malicious websites could submit registration forms on behalf of users without their knowledge. An attacker could create a webpage that automatically creates accounts when someone visits it.

Related: REVCON-959, PR #1528

The Problem

CSRF attacks let malicious sites perform actions as if the user did them. For registration, this means:

  • Creating unwanted accounts
  • Flooding our system with fake registrations
  • Using up server resources

Example attack: A user visits evil-site.com which contains a hidden form that posts to our registration endpoint. The user never intended to create an account, but one gets created anyway.

Our Solution

We use CSRF tokens - unique codes that prove the form was loaded from our website:

  1. When loading the registration page: Generate a random token and store it in DynamoDB
  2. In the form: Include the token as a hidden field
  3. When submitting: Verify the token exists and delete it (one-time use)
  4. If invalid: Reject the request

How It Works

Files involved:

  • app/services/csrf.server.ts - Creates and validates tokens
  • app/routes/registration/$product/registration-form-schema.server.ts - Validates tokens in form submission
  • app/routes/registration/$product/_index.tsx - Generates tokens for each page load

Process:

  1. User visits registration page → we generate a UUID token → store in DynamoDB (expires in 15 minutes)
  2. Form includes hidden <input name="csrfToken" value="..." />
  3. User submits form → we check if token exists in DynamoDB → delete it → proceed with registration
  4. Malicious sites can't get valid tokens because they can't load our page

Technical Details

Storage: DynamoDB table (configured via APP_CSRF_TOKEN_TABLE environment variable)
Token lifetime: 15 minutes
Token format: UUID v4
Validation: Server-side only, integrated with Zod schema validation

Trade-offs

Benefits:

  • Stops cross-site form submissions
  • Works without JavaScript
  • Scales with DynamoDB

Costs:

  • Extra DynamoDB read/write per form submission
  • Users need new tokens if they refresh the page
  • Slightly more complex local development setup

This simple approach effectively prevents CSRF attacks while keeping the user experience unchanged.