T09 · Insecure Skill Coding Practices
- Location
lib/server.js:4642- Finding
Default Unauthenticated Binding Exposes Sensitive OpenClaw Dashboard Data
- Content
View full analysis
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; } ``` The sensitive session endpoint is consequently reachable without authorization: ```js } else if (pathname === "/api/session") { const sessionKey = query.get("key"); if (!sessionKey) { res.writeHead(400, { "Content-Type": "application/json" }); res.end(JSON.stringify({ error: "Missing session key" })); return; } const detail = sessions.getSessionDetail(sessionKey); res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify(detail, null, 2)); ``` Although configuration declares a host, the listener ignores it: ```js server.listen(PORT, () => { const profile = process.env.OPENCLAW_PROFILE; console.log( `\u{1F99E} OpenC ...[truncated 3299 chars]- Remediation
View remediation
{ // Startup handling }); ``` 2. Use an unambiguous loopback address as the default: ```js host: process.env.HOST || fileConfig.server?.host || "127.0.0.1", ``` 3. Fail closed when a non-loopback host is selected without authentication. For example, reject startup if `auth.mode === "none"` and the configured host is not a recognized loopback address. 4. Require authentication for every endpoint that returns workspace, session, transcript, user, job, cron, memory, billing, or system information. 5. Require authentication and explicit authorization for every state-changing route. Job execution and termination should use a separate administrative authorization policy. 6. Consider replacing the global `none` mode with a loopback-only development mode that verifies the actual socket address rather than merely skipping authentication. 7. Do not rely on the startup URL as a security control. Log the actual bound address and whether authentication is enabled. 8. Add automated integration tests that: - Confirm the default listener is reachable only through loopback. - Confirm sensitive endpoints reject unauthenticated requests when listening on a non-loopback interface. - Confirm all mutating endpoints require an authorized identity. - Confirm the server refuses insecure combinations of network binding and authentication settings. ]]>
