# Security Fixes Log Tracks remediation progress against findings in `SECURITY_AUDIT.md`. --- ## C1. Weak JWT Secret — FIXED **Ref:** SECURITY_AUDIT.md > C1 **Changes:** - `src/servers/jwt.ts` — Added startup guard that throws if `JWT_SECRET` is absent or shorter than 32 characters - `.env.example` — Updated placeholder to `` **Note:** The actual `.env` secret must be rotated manually per deployment. --- ## C2. Global CORS Wildcard on All API Routes — FIXED **Ref:** SECURITY_AUDIT.md > C2 **Changes:** - `src/servers/hono.ts` — Replaced `origin: '*'` with dynamic origin validation using the `ALLOWED_ORIGINS` allowlist from `origin-validation.ts` --- ## C3. Server-Settings Routes Entirely Unauthenticated — FIXED **Ref:** SECURITY_AUDIT.md > C3 **Changes:** - `src/servers/hono.ts` — Moved `serverSettingsRouter` inside `protectedRouter` - `src/servers/api/server-settings/server-settings.ts` — Added Super Admin role checks on all write operations - `src/servers/_middlewares/super-admin-middleware.ts` — New middleware for Super Admin enforcement - Exempted `GET /api/server-settings/onboarding-complete` as public (mounted before auth) --- ## C4. Unauthenticated Dev-Server WebSocket Proxy — FIXED **Ref:** SECURITY_AUDIT.md > C4 **Changes:** - `src/servers/api/dev-server/router.ts`: - Replaced slug-based proxy URLs with server-generated UUID v4 (`proxyId`). Proxy lookup is now by UUID, eliminating cross-user slug collisions. - Added `proxyIdIndex` map for O(1) lookup and `pendingStarts` guard against duplicate spawns. - JWT validation required on HTML requests (`Accept: text/html`) — the iframe entry point. Sub-resources pass on proxyId alone (browsers can't add custom headers to native loads). - `?token=` query param stripped before forwarding to dev server. - `proxyOverrideScript` extended to inject `Authorization: Bearer` headers on fetch/XHR and append `?token=` on WebSocket connections, reading fresh tokens from localStorage. - `src/server.tsx`: - WebSocket upgrades require `?token=` query param. Token stored in `WSData.wsToken` for deferred async validation in the `open` handler (Bun requires synchronous `server.upgrade()`). - `devServerWebsocket.open` validates JWT + blacklist check before opening upstream connection. Closes with code `4001` if invalid. - `src/workspaces/officerdev/src/apps/Preview/PreviewProvider.tsx`: - `startServer` and status check `useEffect` append `?token=` to iframe URL using `client.token`. **Security model:** Two-layer capability — proxyId (unguessable UUID) as primary token, JWT as defense-in-depth on entry points (HTML, WebSocket). --- ## C5. AI Chat Messages Rendered with `rehype-raw` — LLM-Driven XSS — FIXED **Ref:** SECURITY_AUDIT.md > C5 **Changes:** - Installed `rehype-sanitize` (v6) - `src/workspaces/officerdev/src/apps/Chat/components/MessageBubble.tsx`: - Added `rehypeSanitize` with a schema that strips `