T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/iron-heartbeat.js:202
- Finding
- Reviewer-Controlled Instructions Are Executed as Unrestricted Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/iron-heartbeat.js:202-223` **Vulnerability Type**: Arbitrary command execution without an effective sandbox **Risk Level**: Critical ### Vulnerable Code ```javascript function executeInSandbox(instructions, task) { console.log('🏃 执行指令...'); const outputDir = path.join(OUTPUTS_DIR, task.task_id); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } logEvent('execution_started', { task_id: task.task_id, instructions_length: instructions.length }); try { // 方法 1: 直接执行(开发环境) // 生产环境应该使用 Docker 或 nsjail 沙箱 const output = execSync(instructions, { cwd: outputDir, encoding: 'utf8', stdio: 'pipe', timeout: 300000 // 5 分钟超时 }); ``` ### Technical Analysis `task.review.next_instructions` is passed directly to `child_process.execSync`. Node.js therefore invokes a system shell and interprets shell operators, substitutions, pipelines, redirections, and additional commands. Despite the function name `executeInSandbox`, the implementation has no process, filesystem, network, credential, or privilege isolation. Setting `cwd` only changes the initial working directory. Commands can still access absolute paths, traverse outside the output directory, read environment variables, contact external hosts, and modify any resource available to the heartbeat process. A timeout limits execution duration but does not reduce privileges or prevent destructive actions. ### Attack Path 1. An attacker supplies or influences a review object containing: ```json { "verdict": "approve", "next_instructions": "attacker-controlled shell commands" } ``` 2. `apply-review.js` stores the review and changes the task state to `reviewed`. 3. A scheduled or manually invoked `iron-heartbeat.js` identifies the reviewed task. 4. `executeTask()` passes `review.next_instructions` to `executeInSandbox()`. 5. `execSync()` ex ...[truncated 699 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove execution of free-form model-generated shell text. 2. Replace `next_instructions` with a typed action schema containing explicitly supported operations, commands, and arguments. 3. Invoke commands using `spawnSync(executable, args, { shell: false })`. 4. Enforce a deny-by-default executable and argument allowlist. 5. Require explicit human approval before network access, package installation, or operations outside the task output directory. 6. Execute tasks in an ephemeral container or namespace with: - A non-root UID. - No inherited secrets. - A read-only base filesystem. - A task-specific writable mount. - Disabled or tightly restricted networking. - CPU, memory, process, and time limits. 7. Canonicalize and validate every mounted or writable path. 8. Fail closed if isolation cannot be established. ]]>
