Security

Overview of security measures and best practices implemented across the application.

Rate Limiting

Protection

Rate limiting is implemented using Upstash Redis to prevent abuse and DDoS attacks.

Rate Limit Implementation

Example of rate limiting in server actions:

import { Ratelimit } from "@upstash/ratelimit"
import { redis } from "@/lib/upstash"

const ratelimit = new Ratelimit({
  redis,
  limiter: Ratelimit.slidingWindow(5, "1 m"), // 5 requests per minute
})

export async function protectedAction() {
  const identifier = `ratelimit:action:${user.id}`
  const { success } = await ratelimit.limit(identifier)

  if (!success) {
    throw new RateLimitError()
  }
  
  // Action implementation...
}

Server Actions

Authentication

Authentication Check

Every server action verifies user authentication

const { user } = await getCurrentUser()
if (!user) {
  throw new AuthenticationError()
}

Input Validation

All inputs are validated using Zod schemas

const validateInput = schema.safeParse(input)
if (!validateInput.success) {
  throw new ValidationError()
}

Permission Check

Actions verify user permissions before execution

const hasPermission = await checkPermission(user.id, "action:name")
if (!hasPermission) {
  throw new AuthorizationError()
}

API Endpoints

Authentication

  • JWT token validation
  • Session verification
  • Role-based access control
  • Secure cookie handling

Protection

  • Rate limiting per endpoint
  • Input sanitization
  • CORS configuration
  • HTTP-only cookies

Security Best Practices

Data Protection

  • Encrypt sensitive data
  • Use HTTPS only
  • Implement proper CORS
  • Secure cookie settings

Authentication

  • Strong password policies
  • MFA when available
  • Session management
  • Regular token rotation

Error Handling

Standardized error handling for security-related issues:

Custom Error Types

Security-focused error handling:

// Custom error types
export class AuthenticationError extends ApiError {
  constructor(message = "Not authenticated") {
    super(401, message)
  }
}

export class AuthorizationError extends ApiError {
  constructor(message = "Not authorized") {
    super(403, message)
  }
}

export class RateLimitError extends ApiError {
  constructor(message = "Too many requests") {
    super(429, message)
  }
}