This document outlines the security measures implemented in CaseRadar to protect user data, prevent attacks, and ensure compliance.
- Security Headers
- Input Sanitization
- Authentication & Authorization
- Audit Logging
- Data Protection
- API Security
- Infrastructure Security
CaseRadar implements comprehensive HTTP security headers to protect against common web vulnerabilities.
| Header | Value | Purpose |
|---|---|---|
X-DNS-Prefetch-Control |
off |
Prevents DNS prefetching privacy leaks |
Strict-Transport-Security |
max-age=63072000; includeSubDomains; preload |
Enforces HTTPS for 2 years |
X-Frame-Options |
DENY |
Prevents clickjacking attacks |
X-Content-Type-Options |
nosniff |
Prevents MIME type sniffing |
Referrer-Policy |
strict-origin-when-cross-origin |
Controls referrer information |
Permissions-Policy |
camera=(), microphone=()... |
Restricts browser features |
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://api.clerk.dev https://api.stripe.com;
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
import { getSecurityHeaders, getCSPHeader } from '@/lib/security';
// In Next.js middleware or API routes
const headers = getSecurityHeaders();
const csp = getCSPHeader({ production: true });All user input is sanitized before processing to prevent injection attacks.
import { sanitizeHtml, escapeHtml } from '@/lib/security';
// Remove dangerous HTML
const safe = sanitizeHtml('<script>alert("XSS")</script>Hello');
// Result: "Hello"
// Escape for display
const escaped = escapeHtml('<div onclick="alert(1)">');
// Result: "<div onclick="alert(1)">"While CaseRadar uses Prisma ORM with parameterized queries (primary defense), we also provide escape functions for defense in depth:
import { escapeForSql, sanitizeSearchQuery } from '@/lib/security';
// Escape for SQL (defense in depth)
const safe = escapeForSql("O'Brien; DROP TABLE users;--");
// Result: "O''Brien DROP TABLE users"
// Sanitize search queries
const query = sanitizeSearchQuery('search<script>alert(1)</script>');
// Result: "searchalert1"import { validateInput } from '@/lib/security';
validateInput('test@example.com', 'email'); // true
validateInput('550e8400-e29b-41d4-a716-446655440000', 'uuid'); // true
validateInput('https://example.com', 'url'); // true
validateInput('2024-01-15', 'date'); // true
validateInput('abc123', 'alphanumeric'); // trueimport { sanitizeFilename } from '@/lib/security';
// Prevent path traversal
const safe = sanitizeFilename('../../../etc/passwd');
// Result: "etcpasswd"CaseRadar uses Clerk for authentication with a custom RBAC layer.
- User Login: Handled by Clerk's secure authentication
- Session Management: Clerk manages sessions with secure cookies
- Webhook Sync: User/org data synced via Svix-verified webhooks
| Role | Permissions |
|---|---|
ADMIN |
Full access - manage users, billing, settings |
ANALYST |
Create/edit patterns, generate complaints |
VIEWER |
Read-only access to dashboards and reports |
All data is scoped by organizationId:
// Every query includes tenant isolation
const complaints = await prisma.complaint.findMany({
where: {
organizationId: currentOrg.id, // Tenant isolation
// ... other filters
}
});import { withAuth, withRole, withOrganization } from '@/lib/auth';
// Protect API routes
export const GET = withAuth(
withOrganization(
withRole(['ADMIN', 'ANALYST'], async (req, ctx) => {
// Route handler
})
)
);CaseRadar maintains a comprehensive audit trail for compliance and security monitoring.
| Category | Events |
|---|---|
| Authentication | LOGIN, LOGOUT, LOGIN_FAILED |
| Data Access | READ, EXPORT |
| Data Modification | CREATE, UPDATE, DELETE |
| Admin Actions | PERMISSION_CHANGE, IMPORT |
interface AuditLogEntry {
userId: string | null;
organizationId: string | null;
action: AuditAction;
resource: AuditResource;
resourceId: string | null;
metadata?: Record<string, unknown>;
ipAddress?: string;
userAgent?: string;
createdAt: Date;
}Audit logs automatically redact sensitive fields:
import { filterSensitiveData } from '@/lib/security';
const data = { email: 'user@example.com', password: 'secret123' };
const filtered = filterSensitiveData(data);
// Result: { email: 'user@example.com', password: '[REDACTED]' }import { createAuditLog, logAuthEvent, logDataAccess } from '@/lib/security';
// Log authentication
await logAuthEvent('LOGIN', userId, { method: 'oauth' }, ipAddress);
// Log data access
await logDataAccess(userId, orgId, 'COMPLAINT', complaintId);
// Log data modification
await createAuditLog({
userId,
organizationId,
action: 'UPDATE',
resource: 'PATTERN',
resourceId: patternId,
metadata: { field: 'severity', oldValue: 'medium', newValue: 'high' }
});- In Transit: TLS 1.3 enforced via HSTS
- At Rest: Database encryption via Supabase
- Vectors: Complaint embeddings stored in pgvector
- Audit logs: 90 days (configurable per plan)
- Generated complaints: Until user deletion
- NHTSA data: Synchronized with source
- Data export functionality for user requests
- Account deletion cascades all user data
- Consent management via organization settings
| Endpoint Category | Limit |
|---|---|
| Authentication | 5/minute |
| Search queries | 60/minute |
| Complaint generation | 10/minute |
| Data export | 5/hour |
All API endpoints validate:
- Authentication: Valid session token
- Authorization: Role-based permissions
- Tenant: Organization membership
- Input: Schema validation with Zod
Security-sensitive errors return generic messages:
// ❌ Don't expose internal details
return new Response('User not found in database', { status: 404 });
// ✅ Generic error response
return new Response('Not found', { status: 404 });- DDoS protection
- Edge network with global CDN
- Automatic HTTPS certificates
- Preview deployments isolated
- SOC 2 Type 2 certified
- Row Level Security (RLS)
- Encrypted backups
- Network isolation
- Environment variables via Vercel
- API keys rotated quarterly
- Webhook secrets verified with Svix
- Unit Tests: 68 security-specific tests
- E2E Tests: 132 browser tests including accessibility
- Static Analysis: ESLint security rules
# Run security tests
npm test -- --run src/lib/security/__tests__/
# Run all tests
npm test- SQL injection vectors
- XSS via user input
- CSRF protection
- Authentication bypass
- Authorization escalation
- Sensitive data exposure
- Rate limit bypass
Report vulnerabilities to: security@caseradar.com
| Severity | Initial Response | Resolution Target |
|---|---|---|
| Critical | 4 hours | 24 hours |
| High | 24 hours | 7 days |
| Medium | 72 hours | 30 days |
| Low | 1 week | 90 days |
- OWASP Top 10 mitigations
- WCAG 2.1 Level AA accessibility
- SOC 2 Type 2 (via infrastructure)
- Quarterly dependency audits
- Annual penetration testing
- Continuous monitoring via Vercel
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2026-01-12 | Initial security architecture |