From b6a0a57893d00657f9362a248fcadcf82af722c9 Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Wed, 25 Feb 2026 16:04:11 +0000 Subject: [PATCH] thinking --- SECURITY_AUDIT.md | 593 ++++++++++++++++++ src/servers/api/pi/pi-bridge.ts | 10 + src/servers/api/pi/types.ts | 3 + src/servers/api/pi/websocket.ts | 7 +- .../api/server-settings/sync-pi-config.ts | 16 +- .../apps/Chat/ChatLauncher/ChatLauncher.tsx | 2 + .../Chat/EmbeddableChat/useEmbeddableChat.ts | 5 + .../src/apps/Chat/components/InputArea.tsx | 4 + .../apps/Chat/components/ModelSelector.tsx | 73 ++- .../components/TaskRunnerModal.tsx | 2 + .../officerdev/src/hooks/usePiChat.ts | 5 + 11 files changed, 698 insertions(+), 22 deletions(-) create mode 100644 SECURITY_AUDIT.md diff --git a/SECURITY_AUDIT.md b/SECURITY_AUDIT.md new file mode 100644 index 00000000..9f9dee81 --- /dev/null +++ b/SECURITY_AUDIT.md @@ -0,0 +1,593 @@ +# Security Audit — Officer.dev Pi-Monorepo + +**Date:** 2026-02-25 +**Scope:** Full-stack audit of server, frontend, and infrastructure code. + +--- + +## Executive Summary + +The codebase has solid foundations (JWT + argon2 auth, WebAuthn passkeys, token blacklisting, Docker-sandboxed terminals, role-based access control). However, several critical and high-severity vulnerabilities exist — primarily around CORS misconfiguration, weak secret management, unauthenticated admin routes, XSS via `rehype-raw`, and token exposure in URLs. + +**Totals:** 5 Critical, 13 High, 14 Medium, 9 Low, 5 Info + +--- + +## CRITICAL + +### C1. Weak JWT Secret — `"officer"` + +**Files:** `.env` (line 2), `src/servers/jwt.ts` (lines 2, 25) + +The live `.env` contains `JWT_SECRET="officer"` — a single dictionary word. The `.env.example` uses `"change-me"`. The server uses a non-null assertion (`JWT_SECRET!`) with no startup validation for length or complexity. + +**Impact:** Complete authentication bypass. Anyone who knows/guesses the secret can forge JWTs for any user including Super Admin. + +**Remediation:** +- Generate a cryptographically random secret: `openssl rand -base64 32` +- Add a startup guard: throw if `JWT_SECRET` is absent or shorter than 32 characters +- Update `.env.example` with a placeholder: `JWT_SECRET=` + +--- + +### C2. Global CORS Wildcard on All API Routes + +**File:** `src/servers/hono.ts` (lines 36–42) + +```ts +cors({ origin: '*', allowHeaders: ['Content-Type', 'Authorization'] }) +``` + +Applied to every route. The `Authorization` header allowlist means any website can make cross-origin requests using a victim's token (obtained via XSS or other leaks). + +**Impact:** Full cross-origin request forgery against all API endpoints for users tricked into visiting a malicious page. + +**Remediation:** Replace `origin: '*'` with the allowlist from `origin-validation.ts` (`ALLOWED_ORIGINS`). Use a dynamic origin validation function in the CORS middleware. + +--- + +### C3. Server-Settings Routes Entirely Unauthenticated + +**Files:** `src/servers/hono.ts` (lines 46–48), `src/servers/api/server-settings/server-settings.ts` + +The `serverSettingsRouter` is mounted on the **public** router (outside `protectedRouter`). All sub-routes — SMTP, TTS, STT, OCR, SearXNG, Pi-Mono, Claude Code, OpenCode, applications, resources — have no auth checks. Any unauthenticated request can read settings (including masked credentials), write new settings, and trigger software installs. + +**Impact:** Full server configuration takeover by any unauthenticated user. + +**Remediation:** Move `serverSettingsRouter` inside `protectedRouter`. Add Super Admin role checks on all write operations. Exempt only `GET /api/server-settings/onboarding-complete` as public. + +--- + +### C4. Unauthenticated Dev-Server WebSocket Proxy + +**Files:** `src/server.tsx` (lines 114–139), `src/servers/api/dev-server/router.ts` (lines 241–268), `src/servers/hono.ts` (line 49) + +The dev-server proxy (`/api/dev-server-proxy/*`) is mounted on the public router. WebSocket upgrades carry no authentication. The HTTP proxy has no auth gate either. Additionally, the Referer header fallback allows probing any running dev server. + +**Impact:** Unauthenticated access to dev-servers spawned for any user, which may expose internal APIs, HMR endpoints, or local services. + +**Remediation:** Require a valid JWT (via query param) before upgrading WebSocket connections. Apply `userMiddleware` to the HTTP proxy router. + +--- + +### C5. AI Chat Messages Rendered with `rehype-raw` — LLM-Driven XSS + +**File:** `src/workspaces/officerdev/src/apps/Chat/components/MessageBubble.tsx` (lines 132, 181) + +```tsx +{assistantText} +``` + +AI-generated assistant responses containing HTML tags (`