T05 · Unauthorized Access and Privilege Escalation
- Location
src/websocket-server.ts:38- Finding
Unauthenticated Network Clients Can Submit Arbitrary Messages to the OpenClaw Agent
- Content
View full analysis
{ const deviceId = req.url?.split("?")[0].slice(1) || "unknown"; console.log(`🎤 XiaoZhi device connected: ${deviceId}`); const audioStream = createAudioStream(AUDIO_CONFIG); const doubaoService = createDoubaoService(DOUBAO_CONFIG); clients.set(deviceId, { ws, audioStream, audioBuffer: [], isListening: false, doubaoService, }); ws.on("message", async (data: Buffer) => { try { const message: XiaoZhiMessage = JSON.parse(data.toString()); await handleXiaozhiMessage(deviceId, message, ctx); } catch (error) { ``` The resulting text is forwarded directly to the agent: ```ts const response = await ctx.agent.processMessage({ from: deviceId, text: userText, channel: "xiaozhi", }); ``` The channel also enables permissive quick-start behavior: ```ts meta: { ...meta, quickstartAllowFrom: true, }, ``` ### Technical Analysis `WebSocketServer` is created with only a port, so it listens on the default network interfaces. The connection handler does not validate a bearer token, client certificate, signed challenge, approved pairing record, source address, or WebSocket origin. The client controls its apparent identity through the request URL: ```ts const deviceId = req.url?.split("?")[0].slice(1) || "unknown"; ``` That value is accepted as the sender identity without verification. A JSON `listen/stop` message can contain an arbitrary `text` property, which is subsequently passed to `ctx.agent.processMessage`. Consequently, network reachability to the configured port is sufficient to invoke the agent. Although a pairing adapter ...[truncated 1552 chars]- Remediation
View remediation
