{"id":"GHSA-3298-56p6-rpw2","summary":"OpenClaw has incomplete Fix for CVE-2026-27486: Unvalidated SIGKILL in `!stop` Chat Command via `shell-utils.ts`","details":"\u003e Fixed in OpenClaw 2026.3.24, the current shipping release.\n\n### Advisory Details\n**Title**: Incomplete Fix for CVE-2026-27486: Unvalidated SIGKILL in `!stop` Chat Command via `shell-utils.ts`\n\n**Description**:\n### Summary\nThe `!stop` (and `/bash stop`) chat command kills background bash processes using `SIGKILL` directly, without first sending `SIGTERM` to allow graceful shutdown. This is because `bash-command.ts` imports `killProcessTree()` from `src/agents/shell-utils.ts`, which still contains the pre-CVE-2026-27486 aggressive kill logic, rather than from the patched `src/process/kill-tree.ts`.\n\n### Details\nCVE-2026-27486 fixed unsafe process termination by introducing a graceful shutdown sequence in `src/process/kill-tree.ts` — sending `SIGTERM` first, waiting a configurable grace period (default 3 seconds), then escalating to `SIGKILL` only if the process is still alive.\n\nHowever, an identical copy of the **unpatched** `killProcessTree` function remains in `src/agents/shell-utils.ts` (lines 170–192). This function sends `SIGKILL` immediately with no `SIGTERM`:\n\n```typescript\n// src/agents/shell-utils.ts:170-192\nexport function killProcessTree(pid: number): void {\n  // ... Windows handling ...\n  try {\n    process.kill(-pid, \"SIGKILL\"); // Immediate hard kill, no SIGTERM\n  } catch {\n    try {\n      process.kill(pid, \"SIGKILL\");\n    } catch {\n      // process already dead\n    }\n  }\n}\n```\n\nThe `!stop` chat command handler in `src/auto-reply/reply/bash-command.ts` imports and calls this vulnerable version at line 302:\n\n```typescript\n// src/auto-reply/reply/bash-command.ts:5\nimport { killProcessTree } from \"../../agents/shell-utils.js\";\n\n// src/auto-reply/reply/bash-command.ts:300-304\nconst pid = running.pid ?? running.child?.pid;\nif (pid) {\n  killProcessTree(pid);  // Calls the UNPATCHED version\n}\nmarkExited(running, null, \"SIGKILL\", \"failed\");\n```\n\nCompare this to the patched version in `src/process/kill-tree.ts`:\n\n```typescript\n// src/process/kill-tree.ts:46-78\nfunction killProcessTreeUnix(pid: number, graceMs: number): void {\n  // Step 1: Try graceful SIGTERM to process group\n  try {\n    process.kill(-pid, \"SIGTERM\");\n  } catch { /* ... */ }\n\n  // Step 2: Wait grace period, then SIGKILL if still alive\n  setTimeout(() =\u003e {\n    if (isProcessAlive(-pid)) {\n      try { process.kill(-pid, \"SIGKILL\"); } catch { /* ... */ }\n    }\n  }, graceMs).unref();\n}\n```\n\n### PoC\n\nThis PoC demonstrates the difference between the vulnerable and patched code paths inside a running OpenClaw Gateway container.\n\n**Setup:**\n```bash\n# Build and start the gateway container\ncd CVE-2026-27486-variant-exp/\ndocker compose up -d\nsleep 5\n```\n\n**Exploit (vulnerable `killProcessTree` from `shell-utils.ts`):**\n\nThe following script is injected into the container and executed. It starts a bash process that traps `SIGTERM` for graceful shutdown, then kills it using the same code path as `!stop`:\n\n```javascript\n// exploit_sigkill.cjs — replicates src/agents/shell-utils.ts:183-190\nconst { spawn } = require('child_process');\nconst fs = require('fs');\n\ntry { fs.unlinkSync('/tmp/graceful_shutdown.txt'); } catch {}\n\nconst child = spawn('/bin/bash', ['-c',\n  'trap \\'echo GRACEFUL_SHUTDOWN \u003e /tmp/graceful_shutdown.txt; exit 0\\' SIGTERM; while true; do sleep 1; done'\n], { detached: true, stdio: 'ignore' });\nchild.unref();\n\nsetTimeout(() =\u003e {\n  // VULNERABLE: same as shell-utils.ts — SIGKILL only\n  try { process.kill(-child.pid, 'SIGKILL'); } catch {\n    try { process.kill(child.pid, 'SIGKILL'); } catch {}\n  }\n  setTimeout(() =\u003e {\n    if (fs.existsSync('/tmp/graceful_shutdown.txt')) {\n      console.log('[BLOCKED] SIGTERM was received.');\n      process.exit(1);\n    } else {\n      console.log('[EXPLOITED] SIGKILL sent directly — SIGTERM never delivered.');\n      process.exit(0);\n    }\n  }, 2000);\n}, 1000);\n```\n\n**Run:**\n```bash\npython3 poc_exploit.py\n```\n\n### Log of Evidence\n\n**Exploit output (SIGKILL only, no graceful shutdown):**\n```\n[*] Running exploit (vulnerable killProcessTree from shell-utils.ts)...\n[*] Victim PID: 78\n[*] Calling vulnerable killProcessTree (SIGKILL only, no SIGTERM)...\n[EXPLOITED] SIGKILL sent directly — SIGTERM never delivered.\n[EXPLOITED] Graceful shutdown handler was NEVER invoked.\n\n[SUCCESS] CVE-2026-27486 variant confirmed:\n  killProcessTree() in shell-utils.ts sends immediate SIGKILL,\n  bypassing the graceful shutdown fix in process/kill-tree.ts.\n```\n\n**Control output (SIGTERM first, graceful shutdown works):**\n```\n[*] Running control (patched killProcessTree from process/kill-tree.ts)...\n[*] Victim PID: 93\n[*] Calling patched killProcessTree (SIGTERM first, then SIGKILL after grace)...\n[NORMAL] SIGTERM received — graceful shutdown completed. Flag: GRACEFUL_SHUTDOWN\n\n[NORMAL] Control confirmed: patched killProcessTree sends SIGTERM first,\n         allowing graceful shutdown before escalating to SIGKILL.\n```\n\n### Impact\nWhen `!stop` is used, background processes are killed instantly via `SIGKILL` with no chance to perform cleanup. This can result in:\n\n- **Data corruption**: processes writing to files or databases are interrupted mid-write\n- **Resource leaks**: temporary files, lock files, and network connections are not properly released\n- **Security-sensitive cleanup skipped**: operations like erasing in-memory secrets or completing audit logs are bypassed\n\nThis is the same class of impact that CVE-2026-27486 was filed for — the fix simply missed the `shell-utils.ts` copy of the function.\n\n### Affected products\n- **Ecosystem**: npm\n- **Package name**: openclaw\n- **Affected versions**: \u003c= 2026.3.14\n- **Patched versions**: \u003cNone\u003e\n\n### Severity\n- **Severity**: Medium\n- **Vector string**: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H\n\n### Weaknesses\n- **CWE**: CWE-404: Improper Resource Shutdown or Release\n\n### Occurrences\n\n| Permalink | Description |\n| :--- | :--- |\n| [https://github.com/moltbot/moltbot/blob/f2849c2417/src/agents/shell-utils.ts#L170-L192](https://github.com/moltbot/moltbot/blob/f2849c2417/src/agents/shell-utils.ts#L170-L192) | The vulnerable `killProcessTree` function that sends immediate `SIGKILL` without `SIGTERM`. |\n| [https://github.com/moltbot/moltbot/blob/f2849c2417/src/auto-reply/reply/bash-command.ts#L5](https://github.com/moltbot/moltbot/blob/f2849c2417/src/auto-reply/reply/bash-command.ts#L5) | Import statement pulling the vulnerable `killProcessTree` from `shell-utils.ts` instead of the patched `kill-tree.ts`. |\n| [https://github.com/moltbot/moltbot/blob/f2849c2417/src/auto-reply/reply/bash-command.ts#L300-L304](https://github.com/moltbot/moltbot/blob/f2849c2417/src/auto-reply/reply/bash-command.ts#L300-L304) | The `!stop` handler calling the vulnerable `killProcessTree(pid)`. |\n| [https://github.com/moltbot/moltbot/blob/f2849c2417/src/process/kill-tree.ts#L46-L78](https://github.com/moltbot/moltbot/blob/f2849c2417/src/process/kill-tree.ts#L46-L78) | The **patched** `killProcessTreeUnix` with graceful `SIGTERM` → grace period → `SIGKILL` sequence (for reference). |","aliases":["CVE-2026-35667"],"modified":"2026-04-10T17:56:25.298589Z","published":"2026-03-30T18:30:01Z","database_specific":{"nvd_published_at":null,"cwe_ids":["CWE-404"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-03-30T18:30:01Z"},"references":[{"type":"WEB","url":"https://github.com/openclaw/openclaw/security/advisories/GHSA-3298-56p6-rpw2"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-jfv4-h8mc-jcp8"},{"type":"PACKAGE","url":"https://github.com/openclaw/openclaw"}],"affected":[{"package":{"name":"openclaw","ecosystem":"npm","purl":"pkg:npm/openclaw"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"2026.3.24"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-3298-56p6-rpw2/GHSA-3298-56p6-rpw2.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H"}]}