# Issue #192: Fix CORS Configuration for Cookie-Based Authentication ## Objective Fix CORS configuration in the API to properly support cookie-based authentication with credentials across origins. ## Problem Current CORS settings are blocking cookie-based authentication flow. Likely issues: - Credentials not enabled - Wildcard origin with credentials (invalid combination) - Incorrect cookie SameSite settings - Missing Access-Control-Allow-Credentials header ## Approach 1. **Investigation Phase** - Read current CORS configuration in main.ts and app.module.ts - Check authentication module CORS settings - Identify specific blocking issues 2. **TDD Phase** (Red-Green-Refactor) - Write tests for cookie-based auth across origins - Write tests for CORS headers with credentials - Verify tests fail with current configuration 3. **Implementation Phase** - Fix CORS configuration to enable credentials - Configure proper origin handling (no wildcard with credentials) - Set appropriate cookie SameSite settings - Ensure Access-Control-Allow-Credentials header 4. **Verification Phase** - Run all tests (target >85% coverage) - Verify cookie-based auth works - Security review ## Progress - [x] Create scratchpad - [x] Read current CORS configuration - [x] Read authentication module setup - [x] Write tests for cookie-based auth (PASSED) - [x] Implement CORS fixes in main.ts - [x] Verify all tests pass (CORS tests: PASS, Auth tests: PASS) - [x] Security review (see below) - [ ] Commit changes - [ ] Update issue #192 ## Findings ### Current Configuration (main.ts:44) ```typescript app.enableCors(); ``` **Problem**: Uses default CORS settings with no credentials support. ### Better-Auth Configuration (auth.config.ts:31-36) ```typescript trustedOrigins: [ process.env.NEXT_PUBLIC_APP_URL ?? "http://localhost:3000", "http://localhost:3001", // API origin (dev) "https://app.mosaicstack.dev", // Production web "https://api.mosaicstack.dev", // Production API ]; ``` Good! Better-Auth already has trusted origins configured. ## Testing ### Test Scenarios 1. OPTIONS preflight with credentials 2. Cookie transmission in cross-origin requests 3. Access-Control-Allow-Credentials header presence 4. Origin validation (not wildcard) 5. Cookie SameSite settings ### Security Considerations - No wildcard origins with credentials (security violation) - Proper origin whitelist validation - Secure cookie settings (HttpOnly, Secure, SameSite) - CSRF protection considerations ## Security Review ### CORS Configuration Changes ✓ APPROVED **File**: `apps/api/src/main.ts` #### Security Measures Implemented 1. **Origin Whitelist** - Specific allowed origins, no wildcard - `http://localhost:3000` (dev frontend) - `http://localhost:3001` (dev API) - `https://app.mosaicstack.dev` (prod frontend) - `https://api.mosaicstack.dev` (prod API) - Dynamic origin from `NEXT_PUBLIC_APP_URL` env var 2. **Credentials Support** - `credentials: true` - Required for cookie-based authentication - Properly paired with specific origins (NOT wildcard) 3. **Origin Validation Function** - Exact string matching (no regex vulnerabilities) - Rejects untrusted origins with error - Allows requests with no origin (mobile apps, Postman) 4. **Security Headers** - `Access-Control-Allow-Credentials: true` - `Access-Control-Allow-Origin: ` - `Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS` - `Access-Control-Allow-Headers: Content-Type, Authorization, Cookie` - `Access-Control-Expose-Headers: Set-Cookie` - `Access-Control-Max-Age: 86400` (24h preflight cache) #### Attack Surface Analysis - ✅ **No CORS bypass vulnerabilities** - Exact origin matching - ✅ **No wildcard + credentials** - Security violation prevented - ✅ **No subdomain wildcards** - Prevents subdomain takeover attacks - ✅ **Cookie security** - Properly exposed Set-Cookie header - ✅ **Preflight caching** - 24h cache reduces preflight overhead #### Compliance - ✅ **OWASP CORS Best Practices** - ✅ **MDN Web Security Guidelines** - ✅ **Better-Auth Integration** - Aligns with `trustedOrigins` config ### Environment Variables Added `NEXT_PUBLIC_APP_URL` to: - `.env.example` (template) - `.env` (local development) ## Notes **CRITICAL**: This blocks the entire authentication flow. ### Implementation Summary Fixed CORS configuration to enable cookie-based authentication by: 1. Adding explicit origin whitelist function 2. Enabling `credentials: true` 3. Configuring proper security headers 4. Adding environment variable support ### CORS + Credentials Rules - `credentials: true` required for cookies - Cannot use `origin: '*'` with credentials - Must specify exact origins or use dynamic validation - Must set `Access-Control-Allow-Credentials: true` header - Cookies must have appropriate SameSite setting ### Cookie Settings for Cross-Origin - `HttpOnly: true` - Prevent XSS - `Secure: true` - HTTPS only (production) - `SameSite: 'lax'` or `'none'` - Cross-origin support - `SameSite: 'none'` requires `Secure: true`