Form Validation & Security Guide

A comprehensive template for implementing defence-in-depth form security in React and Next.js applications. Covers frontend validation, XSS sanitization, server-side re-validation, and CORS configuration.

Paste into your AI chat

Copy the entire guide as markdown to use as context in Cursor, Claude, ChatGPT, or any AI tool.

Defence-in-Depth Approach

Four layers of protection for your forms.

1

Frontend Validation

Zod schemas for real-time feedback

2

XSS Sanitization

Strip malicious content before submission

3

API Validation

Server-side re-validation (never trust client)

4

CORS Configuration

Restrict allowed origins

Dependencies

Install the required packages for validation and sanitization.

Frontend Validation (Zod Schemas)

Create type-safe validation schemas that run in the browser for instant feedback.

XSS Sanitization

Strip malicious HTML/script content from user inputs before processing.

React Form Component

A complete form component with real-time validation and sanitization on submit.

API Endpoint (Server-Side)

Never trust the client. Re-validate and sanitize everything server-side.

CORS Configuration

Restrict which domains can make requests to your API.

Validation Rules Quick Reference

Field TypeValidation Rules
Name2-100 chars, letters/spaces/hyphens/apostrophes only
EmailValid format, max 254 chars, auto-lowercase
UK Phone07xxx (11 digits), +447xxx (12 digits), or landline
Message10-2000 chars
URLValid URL format with protocol
DropdownMust be one of allowed values (z.enum())
CheckboxBoolean, refine() for required agreement
Arrayz.array() with .min(1) for required selections

Common Patterns

Reusable Zod patterns for typical form fields.

Optional Fields with Empty String Fallback

typescript
comments: z
  .string()
  .max(2000, 'Comments must be less than 2000 characters')
  .optional()
  .or(z.literal('')),

Enum Validation

typescript
subject: z
  .enum(['maths', 'english', 'science'], {
    message: 'Subject must be maths, english, or science',
  }),

Numeric Validation

typescript
results: z.object({
  score: z.number().int().min(0).max(100),
  totalQuestions: z.number().int().min(1).max(100),
}),

Conditional Validation

typescript
phone: z
  .string()
  .max(20)
  .refine(
    (val) => !val || validateUKPhone(val),
    'Please enter a valid UK phone number'
  )
  .optional()
  .or(z.literal('')),

Security Checklist

Use this checklist to verify your implementation is complete.

Frontend

  • Install zod and xss packages
  • Create validation schemas for all forms
  • Implement real-time field validation on blur/change
  • Sanitize all string inputs before submission
  • Display user-friendly error messages
  • Disable submit button during submission

API / Backend

  • Re-validate all inputs server-side (never trust client)
  • Sanitize all inputs before processing/storing
  • Configure CORS to whitelist allowed origins only
  • Return structured error responses with field-level errors
  • Log errors for monitoring (don't expose stack traces)
  • Use HTTPS in production

Want the full guide as context for your AI coding assistant?