Skip to content

Security

The security module bundles several common HTTP security primitives: CSRF token generation and validation, CORS header management, rate limiting, and HTML input sanitization.

Import

ts
import { createSecurity } from '@loewen-digital/fullstack/security'

Basic usage

ts
import { createSecurity } from '@loewen-digital/fullstack/security'

const security = createSecurity({
  csrf: { secret: process.env.CSRF_SECRET! },
  cors: {
    origin: ['https://example.com', 'https://app.example.com'],
    credentials: true,
  },
  rateLimit: {
    windowMs: 60_000,
    max: 100,
  },
})

CSRF protection

ts
// Generate a token (embed in your HTML form)
const token = await security.csrf.token(request)

// Verify the token from an incoming POST
const valid = await security.csrf.verify(request)
if (!valid) {
  return new Response('Forbidden', { status: 403 })
}

CORS

ts
// Apply CORS headers to a response
const response = security.cors.apply(request, new Response('OK'))

// Handle preflight requests
if (request.method === 'OPTIONS') {
  return security.cors.preflight(request)
}

Rate limiting

ts
// Check if the current request is within the rate limit
const result = await security.rateLimit.check(request)

if (result.exceeded) {
  return new Response('Too Many Requests', {
    status: 429,
    headers: { 'Retry-After': String(result.retryAfter) },
  })
}

Input sanitization

ts
// Strip HTML tags from untrusted input
const clean = security.sanitize.stripTags(userInput)

// Escape HTML entities
const escaped = security.sanitize.escape(userInput)

// Allow a specific subset of HTML tags
const allowed = security.sanitize.allowTags(userInput, ['b', 'i', 'a', 'p'])

Config options

OptionTypeDefaultDescription
csrf.secretstringSecret for CSRF token signing
csrf.cookieNamestring'csrf_token'Cookie name for the CSRF token
cors.originstring | string[] | '*''*'Allowed origins
cors.methodsstring[]common verbsAllowed HTTP methods
cors.credentialsbooleanfalseAllow credentials
rateLimit.windowMsnumber60000Rate limit window in milliseconds
rateLimit.maxnumber100Maximum requests per window
rateLimit.keyBy(req) => stringclient IPKey function for rate limit buckets