82 lines
3.5 KiB
Markdown
82 lines
3.5 KiB
Markdown
# 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 `<generate with: openssl rand -base64 32>`
|
|
|
|
**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 `<script>`, `<iframe>`, `<object>`, `<embed>`, `<form>` tags and all `on*` event handler attributes
|
|
- Applied to both `ReactMarkdown` instances (assistant messages + streaming bubble)
|
|
- `rehype-raw` retained so legitimate HTML (tables, `<details>`, etc.) still renders — sanitized before hitting the DOM
|
|
|
|
---
|
|
|
|
## Remaining
|
|
|
|
See `SECURITY_AUDIT.md` for the full list. Next priorities:
|
|
|
|
- **H3** — `rehype-sanitize` for the other 6 Markdown rendering locations
|
|
- **H1/H2** — Move token to `HttpOnly` cookies
|
|
- **H7/M5** — URL validation for git-clone/yt-dlp/scrape
|
|
- **H9/H10** — Rate limiting fixes
|