This document outlines the security measures implemented in OpenChat to protect against common web vulnerabilities.
The following security improvements have been implemented:
- Rate Limiting - Prevents brute force attacks
- CSRF Protection - Prevents cross-site request forgery
- Route Protection - Middleware-level authentication
- Input Validation - Zod schemas for all API inputs
- Security Headers - Protection against XSS, clickjacking, etc.
File: /apps/web/src/app/api/auth/[...all]/route.ts
Implementation:
- IP-based rate limiting on all authentication endpoints
- Default: 10 requests per minute (configurable via
AUTH_RATE_LIMIT) - Prevents brute force password attacks
- Returns 429 status with
Retry-Afterheader when limited
Configuration:
# .env
AUTH_RATE_LIMIT=10 # Max requests per window
AUTH_RATE_WINDOW_MS=60000 # Time window in milliseconds (1 minute)Features:
- Automatic cleanup of expired rate limit buckets
- Memory leak prevention with max bucket limits
- Rate limit headers in all responses
File: /apps/web/src/app/api/chats/route.ts
Implementation:
- Session-token-based rate limiting for chat creation
- Prevents timing attacks by checking rate limit before user validation
- Default: 10 chats per minute per session
Files:
/apps/web/src/lib/csrf.ts- CSRF utilities/apps/web/src/app/api/csrf/route.ts- Token endpoint
Implementation:
- Double Submit Cookie pattern
- Cryptographically secure token generation (32 bytes)
- SHA-256 hashing for timing-safe comparison
- HttpOnly cookies for security
Protected Endpoints:
POST /api/chats- Create chatDELETE /api/chats/[id]- Delete chatPOST /api/chat/send- Send message
File: /apps/web/src/lib/csrf-client.ts
Usage:
import { fetchWithCsrf } from '@/lib/csrf-client';
// Automatically includes CSRF token for POST/PUT/DELETE
const response = await fetchWithCsrf('/api/chats', {
method: 'POST',
body: JSON.stringify({ title: 'New Chat' }),
});Manual usage:
import { withCsrfToken } from '@/lib/csrf-client';
const response = await fetch('/api/chats', await withCsrfToken({
method: 'POST',
body: JSON.stringify({ title: 'New Chat' }),
}));File: /apps/web/src/middleware.ts
Implementation:
- Cookie-based session validation
- Redirects unauthenticated users to sign-in
- Adds security headers to all responses
Protected Routes:
/dashboard/*/chat/*/settings/*
Security Headers:
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
File: /apps/web/src/lib/validation.ts
Schemas:
chatIdSchema- Validates Convex ID formatchatTitleSchema- Max 200 chars, trimmedmessageContentSchema- Max 50,000 charssendMessageSchema- Complete message validation
Usage Example:
import { chatIdSchema, createValidationErrorResponse } from '@/lib/validation';
const validation = chatIdSchema.safeParse(id);
if (!validation.success) {
return createValidationErrorResponse(validation.error);
}All API endpoints now validate inputs:
- Chat IDs are validated against Convex ID format
- Message content length is enforced
- Timestamps are properly coerced and validated
- Invalid inputs return 400 with detailed error messages
File: /apps/web/src/lib/rate-limit.ts
Features:
- Generic rate limiter class
- IP extraction from headers
- Automatic bucket cleanup
- Memory leak prevention
Usage:
import { RateLimiter, getClientIp } from '@/lib/rate-limit';
const limiter = new RateLimiter({
limit: 10,
windowMs: 60_000,
});
export async function POST(request: Request) {
const ip = getClientIp(request);
const result = limiter.check(ip);
if (result.limited) {
return new Response('Too Many Requests', {
status: 429,
headers: { 'Retry-After': result.retryAfter.toString() }
});
}
// Handle request...
}# Auth Rate Limiting
AUTH_RATE_LIMIT=10 # Max auth requests per window
AUTH_RATE_WINDOW_MS=60000 # Auth rate limit window (1 minute)
# Chat Rate Limiting
CHAT_CREATE_RATE_LIMIT=10 # Max chat creation per window
CHAT_CREATE_WINDOW_MS=60000 # Chat creation window (1 minute)
# General
NODE_ENV=production # Enables secure CSRF cookies- Always validate inputs - Use Zod schemas for all API endpoints
- Apply CSRF protection - Use
withCsrfProtectionfor state-changing endpoints - Rate limit sensitive endpoints - Especially auth and resource creation
- Use the validation utilities - Don't write custom validation
- Check security headers - Ensure middleware applies proper headers
- Monitor rate limits - Watch for suspicious patterns
- Review logs - Check for CSRF validation failures
- Update limits - Adjust rate limits based on traffic
- Use HTTPS - Secure cookies require HTTPS in production
- Database backups - Regular backups for data recovery
- In-memory rate limiting - Not suitable for multi-instance deployments
- Solution: Use Redis or distributed cache
- CSRF in stateless apps - Double Submit Cookie has edge cases
- Solution: Consider Synchronizer Token Pattern for critical flows
- No request signing - API requests aren't cryptographically signed
- Solution: Implement HMAC signing for high-security endpoints
# Test auth rate limiting
for i in {1..15}; do
curl -X POST http://localhost:3000/api/auth/sign-in
done
# Should return 429 after 10 requests# Get CSRF token
TOKEN=$(curl -s http://localhost:3000/api/csrf | jq -r .token)
# Make request with token
curl -X POST http://localhost:3000/api/chats \
-H "X-CSRF-Token: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Test"}'# Test invalid chat ID
curl -X DELETE http://localhost:3000/api/chats/invalid-id
# Should return 400 with validation error- Check logs for patterns:
grep "CSRF validation failed" logs/*.log - Identify affected endpoints and IPs
- Consider rotating CSRF secrets (currently stateless)
- Review and update CORS configuration
- Check if using distributed deployment (needs Redis)
- Review IP extraction logic (proxies, load balancers)
- Lower rate limits temporarily
- Implement additional verification (captcha, 2FA)
- Review validation schemas for gaps
- Check for parser vulnerabilities
- Update Zod to latest version
- Add additional sanitization if needed
- Add request ID tracking for better debugging
- Implement rate limiting dashboard
- Add CSRF token rotation
- Enhanced logging with structured events
- Redis-based rate limiting for horizontal scaling
- Request signing for API authentication
- Anomaly detection for unusual patterns
- SOC 2 compliance measures
- Penetration testing