TL;DR
Never trust user input. Validate on client for UX, validate on server for security. Use schema validation (Zod, Yup), sanitize for the output context, and reject rather than try to fix malformed input. These prompts help you implement proper input handling.
Schema Validation Setup
Use this prompt to set up Zod schema validation for all your forms and API endpoints. Your AI will generate reusable field validators, composable form schemas, server-side middleware, and TypeScript type inference from your schemas.
Add Zod Validation
Set up schema-based input validation with Zod.
Framework: Next.js/Express/tRPC
For each form/endpoint, create schemas that:
- Define expected shape of input
- Validate types (string, number, boolean)
- Check constraints (min, max, regex)
- Transform data as needed
- Provide clear error messages
Example schema for user registration:
- email: valid email format
- password: 8+ chars, not common password
- username: 3-20 chars, alphanumeric only
- age: optional, number 13-120
Create:
- Reusable field validators (email, phone, url)
- Form schemas that compose field validators
- Server-side validation middleware
- Type inference for TypeScript
Show how to share schemas between client and server.
Server-Side Validation
Copy this prompt to add server-side input validation middleware to every API route. Your AI will create a validateBody middleware function with schema enforcement, clear 400 error responses, and validation for query params, path params, and file uploads.
Validate API Input
Add server-side input validation to my API routes.
Current problem: API accepts any input without validation
For each endpoint:
- Define expected input schema
- Validate before processing
- Return 400 with clear errors if invalid
- Never trust client validation alone
Implementation for Next.js API/Express:
// Middleware approach const validateBody = (schema) => (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.flatten() }); } req.validatedBody = result.data; next(); };
Also validate:
- Query parameters
- URL path parameters
- Headers (auth tokens, content-type)
- File uploads (type, size)
Client validation is for UX only: Attackers can bypass your JavaScript. Every input must be validated server-side. Client validation just makes the user experience better.
Sanitize HTML Content
This prompt asks your AI to set up DOMPurify-based HTML sanitization for user-generated rich text content. You'll get a configured sanitizer with an allowlist of safe tags and attributes, plus guidance on sanitizing both at input and output time.
Sanitize User HTML
Sanitize user-provided HTML content safely.
Use case: Comments, posts, or profiles with rich text
Using DOMPurify (recommended):
const DOMPurify = require('dompurify'); const { JSDOM } = require('jsdom'); const window = new JSDOM('').window; const purify = DOMPurify(window);
const sanitize = (dirty) => { return purify.sanitize(dirty, { ALLOWED_TAGS: 'p', 'b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li', 'br', ALLOWED_ATTR: 'href', FORBID_TAGS: 'script', 'style', 'iframe', 'form', 'input', FORBID_ATTR: 'onclick', 'onerror', 'onload', 'style' }); };
Sanitize:
- On input (before storing)
- On output (before rendering)
- Both is safest
Never use regex to strip HTML tags - use a proper parser.
Validate URLs and Links
Use this prompt to generate safe URL validation that blocks javascript:, data:, and file: protocol attacks. Your AI will create a validation function with protocol allowlisting, optional domain restrictions, and safe redirect handling.
Safe URL Handling
Validate user-provided URLs to prevent attacks.
Threats:
- javascript: URLs (XSS)
- data: URLs (XSS)
- file: URLs (local file access)
- Open redirect to malicious sites
Safe URL validation:
function isValidUrl(input) { try { const url = new URL(input); // Only allow http and https if (!['http:', 'https:'].includes(url.protocol)) { return false; } // Optional: Allowlist of domains // if (!allowedDomains.includes(url.hostname)) return false; return true; } catch { return false; } }
For redirects:
- Use allowlist of permitted redirect destinations
- Or only allow relative URLs (/path, not //evil.com)
- Never redirect to user-provided absolute URLs
Pro tip: Use TypeScript with Zod for end-to-end type safety. Your validated data gets the correct types automatically, catching errors at compile time.
Should I sanitize on input or output?
Output is more important because context matters. But sanitizing on input too provides defense in depth. Store data in a clean form, then encode appropriately for each output context.
What's the difference between validation and sanitization?
Validation checks if input matches expected format and rejects if not. Sanitization modifies input to remove dangerous content. Prefer validation (reject bad input) over sanitization (fix bad input).
Further Reading
Want to understand the vulnerability before fixing it? These guides explain what's happening and why.
Find Input Validation Gaps
Scan your API for endpoints missing validation.