Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Security Audit Report

Date: February 7, 2026 Scope: Backend codebase (src/backend/)

Executive Summary

This report identifies security vulnerabilities across the backend codebase, categorized by severity. The codebase demonstrates good security practices in many areas (parameterized queries, PKCE, encryption, RBAC) with specific gaps that need addressing.

Overall Security Posture: Moderate — good foundation with critical gaps.

Critical Issues

1. In-Memory Rate Limiting (No Persistence)

File: middleware/ratelimit.ts

Rate limiting uses an in-memory Map that resets on worker cold starts and doesn't share state across instances. Attackers can bypass limits by waiting for cold starts or hitting different isolates.

Recommendation: Use Durable Objects, KV, or Cloudflare's built-in rate limiting.

2. CORS Allows All Origins When ALLOWED_ORIGINS Not Set

File: op.ts

OAuth2 endpoints allow any origin when ALLOWED_ORIGINS is not set, enabling CSRF attacks.

Recommendation: Require ALLOWED_ORIGINS in production. Never default to *.

3. Missing CSRF Protection on Stateful Operations

File: rp.ts

OAuth state is validated, but no CSRF token protection for general POST/PUT/DELETE API operations.

Recommendation: Implement CSRF token validation for all state-changing operations.

High Issues

4-6. SQL Injection Risk in Dynamic Query Construction

Files: idp.ts, roles.ts, users.ts

Dynamic SQL query construction uses string concatenation for column names. While parameters are bound, the pattern is fragile.

`UPDATE identity_providers SET ${updates.join(", ")} WHERE id = ?`

Recommendation: Validate all field names against a strict whitelist before building queries.

7. Error Messages Leak Information

Files: Multiple

Error messages in catch blocks include details that could leak system information.

Recommendation: Return generic error messages to clients; log details server-side only.

8. Missing Input Validation on URL Parameters

File: op.ts

OAuth authorization endpoint parameters lack comprehensive validation.

Recommendation: Validate all query parameters against strict patterns.

9. Authorization Code Replay Prevention Gap

File: op.ts

Authorization codes are deleted after retrieval, but if deletion fails, codes could be reused.

Recommendation: Use atomic operations (DELETE with RETURNING) for one-time consumption.

10. Session Token Not Invalidated on User Disable

File: middleware/auth.ts

Existing session tokens remain valid when a user is disabled until they naturally expire.

Recommendation: Implement token revocation on user disable.

Medium Issues

#IssueFileRecommendation
11Weak rate limiting configurationratelimit.tsStricter limits for auth endpoints
12Missing rate limiting on some endpointsMultipleApply to all endpoints
13CORS credentials inconsistencyindex.ts vs op.tsStandardize configuration
14Hardcoded default issuer/audiencetoken.tsRequire in production, fail fast
15JWKS signing endpoint unauthenticatedjwks.tsAdd auth checks or ensure internal-only
16Refresh token rotation not atomicop.tsUse database transactions
17Missing validation on JWT payloadtoken.tsValidate before signing
18Session expiration not consistentsessions.tsEnforce expiration on all operations
19Missing input sanitizationusers.ts, roles.tsSanitize user input before storage
20Audit logging failures are silentaudit.tsAlert on failures

Low Issues

#IssueRecommendation
21TODO comment about master keyRemove or clarify
22console.error for security eventsUse structured logging
23Missing CSP headersAdd Content-Security-Policy
24Missing HSTS on all routesEnsure HSTS is global
25No master key strength validationValidate at startup
26Missing request ID in some errorsInclude in all responses
27Clock skew tolerance may be too highConsider reducing to 5-10s
28No redirect URI length validationAdd max length check

Positive Practices

  1. All database queries use parameterized statements
  2. PKCE with S256 required for all OAuth flows
  3. Sensitive tokens and secrets encrypted at rest
  4. Proper session tracking and revocation
  5. Role-based access control implemented
  6. SSRF protection for IdP URLs
  7. Zod schemas for request validation
  8. Comprehensive audit logging
  9. Refresh token rotation on refresh
  10. Email verification required for bootstrap admin

Remediation Priority

Immediate (Critical/High)

  1. Replace in-memory rate limiting with Durable Objects/KV
  2. Fix CORS to require ALLOWED_ORIGINS in production
  3. Add CSRF protection for state-changing operations
  4. Harden dynamic SQL query construction
  5. Sanitize error messages returned to clients
  6. Implement atomic authorization code consumption

Short-term (Medium)

  1. Tighten rate limiting configuration
  2. Standardize CORS configuration
  3. Require ISSUER/AUDIENCE environment variables
  4. Implement atomic refresh token rotation

Long-term (Low)

  1. Add CSP headers
  2. Improve logging infrastructure
  3. Validate master key strength at startup