T09 · Insecure Skill Coding Practices
- Location
src/index.js:248- Finding
Unauthenticated Dashboard Listens on All Network Interfaces
- Content
View full analysis
{ // CORS headers res.setHeader("Access-Control-Allow-Origin", "*"); const urlParts = req.url.split("?"); const pathname = urlParts[0]; const query = new URLSearchParams(urlParts[1] || ""); // Fast path for health check if (pathname === "/api/health") { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ status: "ok", port: PORT, timestamp: new Date().toISOString() })); return; } // Auth check (unless public path) const isPublicPath = AUTH_CONFIG.publicPaths.some( (p) => pathname === p || pathname.startsWith(p + "/"), ); if (!isPublicPath && AUTH_CONFIG.mode !== "none") { const authResult = checkAuth(req, AUTH_CONFIG); if (!authResult.authorized) { console.log(`[AUTH] Denied: ${authResult.reason} (path: ${pathname})`); res.writeHead(403, { "Content-Type": "text/html" }); res.end(getUnauthorizedPage(authResult.reason, authResult.user, AUTH_CONFIG)); return; } req.authUser = authResult.user; } ``` ```js // src/index.js:430-434 } else if (pathname === "/api/state") { const fullState = state.getFullState(); res.writeHead(200, { " ...[truncated 4035 chars]- Remediation
View remediation
{ // startup logging }); ``` 2. Default to an unambiguous loopback address such as `127.0.0.1`. 3. Refuse startup when authentication is `none` and the configured address is non-loopback. 4. Require authentication for all sensitive and state-changing API routes. 5. Change CORS from `*` to an explicit allowlist or omit CORS entirely for a same-origin dashboard. 6. Add Origin validation and CSRF protection to mutation endpoints. 7. Emit startup logs showing the actual bound address rather than always displaying a localhost URL. 8. Add automated tests that verify the default listener is unreachable through non-loopback interfaces. ]]>
