From e98ccc9d2dec2b4dcb312dc44ecd62d36448363d Mon Sep 17 00:00:00 2001 From: Theory903 <66315399+Theory903@users.noreply.github.com> Date: Fri, 19 Jun 2026 20:35:01 +0000 Subject: [PATCH] cortex/sec: fix command injection in thalamus process throttling Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .jules/sentinel.md | 5 +++++ .../src/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts | 4 +++- .../openclaw-cortex/openclaw-cortex/src/agents/thalamus.ts | 4 +++- .../cortex/cortex/openclaw-cortex/src/agents/thalamus.ts | 4 +++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 2889074f..70775277 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -2,3 +2,8 @@ **Vulnerability:** Hardcoded API key ("ippoc-secret-key") used as default in `src/cortex/cortex/server.py`. **Learning:** Default configurations for development often make their way into production or expose systems during testing if not explicitly overridden. The system relied on a specific hardcoded string for default auth, which is a Critical vulnerability (CWE-798). **Prevention:** Never provide a hardcoded default for secrets. If a secret is missing, either generate a secure random one at runtime (fail-safe) or refuse to start (fail-secure). + +## 2025-06-19 - Command Injection in Process Throttling +**Vulnerability:** Found `cp.exec(\`renice +10 -p ${signal.payload.pid}\`)` in `thalamus.ts` which allowed command injection via an unvalidated `pid` payload. +**Learning:** Using `child_process.exec` with unvalidated user input creates severe command injection vulnerabilities. Replacing it with `child_process.execFile` neutralizes the threat, but an error callback is required to prevent unhandled promise rejections on spawn failures. +**Prevention:** Always use `execFile` or `spawn` with an array of arguments instead of string concatenation in `exec`. Always provide error callbacks for detached executions. diff --git a/infra/src/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts b/infra/src/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts index 2ddb081e..9e2bd929 100644 --- a/infra/src/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts +++ b/infra/src/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts @@ -76,7 +76,9 @@ export class Thalamus { // Requires permissions, but this is the intent // In a real env, we might wrap this in a sudo-helper or just log it if permission denied import("child_process").then(cp => { - cp.exec(`renice +10 -p ${signal.payload.pid}`); + cp.execFile('renice', ['+10', '-p', String(signal.payload.pid)], (error) => { + if (error) console.error("Failed to renice:", error); + }); }); return `REFLEX: Throttled process ${signal.payload.pid} (renice +10)`; } catch (e) { diff --git a/src/cortex/cortex/openclaw-cortex/openclaw-cortex/src/agents/thalamus.ts b/src/cortex/cortex/openclaw-cortex/openclaw-cortex/src/agents/thalamus.ts index 2ddb081e..9e2bd929 100644 --- a/src/cortex/cortex/openclaw-cortex/openclaw-cortex/src/agents/thalamus.ts +++ b/src/cortex/cortex/openclaw-cortex/openclaw-cortex/src/agents/thalamus.ts @@ -76,7 +76,9 @@ export class Thalamus { // Requires permissions, but this is the intent // In a real env, we might wrap this in a sudo-helper or just log it if permission denied import("child_process").then(cp => { - cp.exec(`renice +10 -p ${signal.payload.pid}`); + cp.execFile('renice', ['+10', '-p', String(signal.payload.pid)], (error) => { + if (error) console.error("Failed to renice:", error); + }); }); return `REFLEX: Throttled process ${signal.payload.pid} (renice +10)`; } catch (e) { diff --git a/src/ippoc/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts b/src/ippoc/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts index 2ddb081e..9e2bd929 100644 --- a/src/ippoc/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts +++ b/src/ippoc/cortex/cortex/openclaw-cortex/src/agents/thalamus.ts @@ -76,7 +76,9 @@ export class Thalamus { // Requires permissions, but this is the intent // In a real env, we might wrap this in a sudo-helper or just log it if permission denied import("child_process").then(cp => { - cp.exec(`renice +10 -p ${signal.payload.pid}`); + cp.execFile('renice', ['+10', '-p', String(signal.payload.pid)], (error) => { + if (error) console.error("Failed to renice:", error); + }); }); return `REFLEX: Throttled process ${signal.payload.pid} (renice +10)`; } catch (e) {