T09 · Insecure Skill Coding Practices
- Location
assets/backend/server.js:176- Finding
Unauthenticated AI Backend Exposed to Websites and Local Network Clients
- Content
View full analysis
{ // Authentication probe that uses the configured API key or local CLI login. // No client authentication is required to invoke it. ... }); app.post("/api/chat", async (req, res) => { const { context = "", question = "", history = [], pageTitle = "", pageUrl = "", } = req.body || {}; ... const stream = query({ prompt, options: { cwd: process.cwd(), model: MODEL, maxTurns: 5, systemPrompt, permissionMode: "default", canUseTool, pathToCodebuddyCode: CODEBUDDY_CLI, env: sdkEnv, }, }); ... }); app.post("/api/stop", (req, res) => { res.json({ status: "stopping" }); setTimeout(() => { killOwnCli(); process.exit(0); }, 300); }); ``` ```js app.listen(PORT, () => { console.log(`\n◉ Web highlight chat backend started: http://localhost:${PORT}`); ... }); ``` ### Technical Analysis The backend does not authenticate requests to `/api/chat`, `/api/auth`, `/api/heartbeat`, or `/api/stop`. The default CORS configuration explicitly permits every web origin. Consequently, JavaScript on an ...[truncated 2334 chars]- Remediation
View remediation
{ console.log(`Backend listening on http://127.0.0.1:${PORT}`); }); ``` 2. Generate a cryptographically random authorization token during deployment or startup: ```js import crypto from "node:crypto"; const CLIENT_TOKEN = process.env.WEBCHAT_CLIENT_TOKEN || crypto.randomBytes(32).toString("hex"); ``` 3. Require the token on every sensitive endpoint, including chat, authentication probes, heartbeat, and stop: ```js function requireClientToken(req, res, next) { const supplied = req.get("X-Webchat-Token"); if (!supplied || supplied !== CLIENT_TOKEN) { return res.status(401).json({ error: "Unauthorized" }); } next(); } app.use("/api/chat", requireClientToken); app.use("/api/auth", requireClientToken); app.use("/api/heartbeat", requireClientToken); app.use("/api/stop", requireClientToken); ``` 4. Restrict CORS to the installed extension's exact `chrome-extension://` origin. Do not default to `*`. 5. Reject missing, `null`, or unexpected `Origin` values as appropriate for the intended client. 6. Add rate limiting, request concurrency limits, and explicit request-size limits. 7. Consider using native messaging or an authenticated local IPC mechanism instead of an unauthenticated HTTP service. 8. Avoid returning unnecessary authentication and internal port metadata from the health endpoint. ]]>
