T01 · Skill Instruction Hijacking
- Location
scripts/task_progress_stream.js:252- Finding
Untrusted Log Content Is Injected into an Agent Chat Session
- Content
View full analysis
{ const payload = JSON.stringify({ sessionKey: session, message }); const child = spawn( "openclaw", ["gateway", "call", "chat.inject", payload], { stdio: ["ignore", "pipe", "pipe"], } ); let out = ""; let err = ""; child.stdout.on("data", (d) => (out += d.toString())); child.stderr.on("data", (d) => (err += d.toString())); child.on("close", (code) => { resolve({ code, out, err }); }); child.on("error", (e) => { resolve({ code: -1, out: "", err: String(e) }); }); }); } // Lines 319–321: command output reaches the progress state. function onLine(line) { state.pushLine(line); logStream.write(line + "\n"); flushState(); } // Lines 395–397: tailed file content also reaches the progress state. for (const line of text.split(/\r?\n/)) { if (line.trim()) state.pushLine(line); } ``` ### Technical Analysis The script treats output from a spawned process and content from a tailed file as trusted chat content. `pushLine()` stores each input line in `state.lastLine`. The `summaryText()` and `finalText()` methods then interpolate that value into a Markdown message, which is submitted to the selected OpenClaw session through `chat.inject`. The only content control applied is length truncation. Truncation does not escape Markdow ...[truncated 1949 chars]- Remediation
View remediation
