T05 · Unauthorized Access and Privilege Escalation
- Location
server/src/index.ts:18- Finding
Unauthenticated API permits unauthorized use of server-side AI and image-hosting credentials
- Content
View full analysis
{ console.log(`Server running at http://localhost:${port}`); }); ``` ```ts router.post("/", async (req: Request, res: Response) => { const apiKey = openai.apiKey; if (!apiKey) { res.status(500).json({ error: "OPENAI_API_KEY is not set" }); return; } const body = req.body as ChatRequestBody; const messages = body?.messages; if (!Array.isArray(messages)) { res.status(400).json({ error: "messages array is required" }); return; } // Upload base64/data URL images to PICUI on the server; keep http(s) URLs as-is const normalized: ChatMessage[] = await Promise.all( messages.map(async (m) => { let image = m.image; if (image && needsPicuiUpload(image)) { try { image = await uploadDataUrlToPicui(image); ``` ```ts await chat(apiKey, normalized, currentRenderData, sendEvent, { baseURL: openai.baseURL, model: openai.model, getMaxTokens: (agent) => getMaxTokens(agent), }); ``` ### Technical Analysis The `/api/chat` route performs privileged operations using the server owner's `OPENAI_API_KEY` and, when images are supplied, `PICUI_TOKEN`. The route has no authentication or authorization check. The application also enables permissive CORS through `cors()` with default settings and does not explicitly bind the listener to the loopback interface. Consequently, any party capable of reaching port 3001 can cause the server to make owner-funded AI requests and PICUI uploads. Browser-based requests can also originate from arbitrary websites because the ...[truncated 1796 chars]- Remediation
View remediation
{ console.log(`Server running at http://${host}:${port}`); }); ``` 2. Replace unrestricted CORS with an explicit allowlist, such as `http://localhost:5173`, and reject unrecognized origins. 3. Require authentication for every privileged endpoint. For local use, generate a random per-session bearer token and require the client to provide it. 4. Add per-client and global rate limits, concurrency limits, request timeouts, and maximum SSE stream durations. 5. Limit the number and length of messages and validate the complete request schema at runtime. 6. Enforce strict encoded and decoded image-size limits before allocating buffers or uploading content. 7. Configure finite model-output token limits rather than allowing an undefined maximum. 8. Add spending limits and quota alerts at both OpenAI and PICUI. 9. Avoid exposing the development service through public network interfaces, reverse proxies, or tunnels unless production-grade access controls are enabled. ]]>
