Input Validation and Sanitization (ST-203)
Overview
Implements comprehensive input validation using Zod schemas and XSS prevention via sanitization utilities. All API endpoints validate request bodies, and user inputs are sanitized before processing.
Validation
Zod Schemas
Location: apps/web/src/lib/schemas/auth.ts
Pre-defined schemas for common validation:
emailSchema- Email format and length validationpasswordSchema- Password strength requirementsregisterSchema- Registration request validationloginSchema- Login request validation
Usage Example
import { validateRequest } from '@/lib/validation';
import { registerSchema } from '@/lib/schemas/auth';
export async function POST(request: Request) {
const result = await validateRequest(request, registerSchema);
if (!result.success) {
return NextResponse.json(
{ error: result.error.error, details: result.error.details },
{ status: 400 }
);
}
const { email, password } = result.data; // Type-safe!
// Process validated data...
}
Validation Rules
Email:
- Required field
- Valid email format
- Maximum 255 characters
Password:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
- Maximum 128 characters
Sanitization
String Sanitization
Location: apps/web/src/lib/validation.ts
- Removes HTML tags (
<and>) - Trims whitespace
- Enforces maximum length (10,000 characters)
- Prevents XSS attacks
Usage Example
import { sanitizeString, sanitizeObject } from '@/lib/validation';
// Sanitize single string
const clean = sanitizeString(userInput);
// Sanitize object recursively
const cleanObject = sanitizeObject({ name: userInput, description: userInput2 });
Object Sanitization
Recursively sanitizes all string values in an object, preserving structure.
SQL Injection Prevention
- All database queries use Prisma ORM
- Prisma uses parameterized queries automatically
- No raw SQL queries with user input
- Type-safe database access
Error Handling
Validation Errors
Validation errors return structured responses:
{
"error": "Invalid email format",
"details": [
{
"path": ["email"],
"message": "Invalid email format"
}
]
}
Development Mode:
- Full error details included
- Helpful debugging information
Production Mode:
- Generic error messages
- No sensitive information leaked
Integration Points
Authentication Endpoints
/api/auth/register- UsesregisterSchema/api/auth/login- UsesloginSchema
Request Validation Flow
- Parse JSON body
- Validate against Zod schema
- Sanitize string inputs
- Process validated data
- Return appropriate errors on failure
Testing
Unit Tests
Location: apps/web/src/lib/__tests__/validation.test.ts
Tests cover:
- Email validation
- Password validation
- Sanitization functions
- Error handling
Integration Tests
Location: apps/web/src/app/api/auth/__tests__/
Tests cover:
- End-to-end validation flows
- Error responses
- Successful requests
Best Practices
- Always validate at the edge - Validate in API route handlers
- Use Zod schemas - Type-safe validation with TypeScript inference
- Sanitize user input - Prevent XSS attacks
- Don't trust client input - Validate even from authenticated users
- Return helpful errors - In development, provide detailed error messages
- Log validation failures - Monitor for attack patterns
Legacy Functions
Deprecated validation functions are kept for backward compatibility:
validateEmail()- UseemailSchemainsteadvalidatePassword()- UsepasswordSchemainstead
These will be removed in a future version.
Future Enhancements
- File upload validation
- Content-Type validation
- Request size limits
- Rate limiting per validation failure
- Custom validation rules per endpoint