T09 · Insecure Skill Coding Practices
- Location
scripts/iron-heartbeat.js:202- Finding
Reviewer-Controlled Instructions Are Executed as Unrestricted Shell Code
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is an automated coding workflow, but it can run model- or review-provided shell commands on a recurring schedule without real sandboxing or strong user control.
Review carefully before installing. Do not enable the cron jobs or run the heartbeat on a workspace containing secrets or valuable files unless the executor is replaced with a real sandbox, task IDs and paths are strictly validated, review inputs are authenticated and schema-checked, and every generated command is approved or constrained to a safe allowlist.
scripts/iron-heartbeat.js:202Reviewer-Controlled Instructions Are Executed as Unrestricted Shell Code
scripts/apply-review.js:81Unauthenticated Review JSON Is Promoted Into Executable Task State
scripts/trigger-review.js:84Untrusted Task Content Can Hijack the Reviewer Prompt
scripts/security-scan.js:10Regex Blacklist Does Not Prevent Dangerous Shell Execution
scripts/heartbeat-coordinator.js:48Task Identifiers Are Interpolated Into Shell Commands
scripts/force-unlock.sh:83Recovery Script Arguments Are Injected Into Inline JavaScript
scripts/activate-queued-tasks.js:38Unvalidated Task IDs Permit Path Traversal and Out-of-Scope JSON Mutation
scripts/iron-heartbeat.js:175Acceptance Verification and Post-Execution Audit Automatically Trust Successful Commands
Referenced artifact was not completely inspected
node scripts/auto-plan.js "更新 references 文档"
Referenced artifact was not completely inspected
node scripts/auto-plan.js "更新 references 文档"
Referenced artifact was not completely inspected
node scripts/auto-plan.js "更新 references 文档"
Referenced artifact was not completely inspected
node scripts/auto-plan.js "更新 references 文档"
Referenced artifact was not completely inspected
node scripts/auto-plan.js "更新 references 文档"
The code explicitly claims to run task instructions "in a sandbox," but actually passes reviewer-controlled next_instructions directly to execSync(...) on the host. Any attacker who can influence task content can achieve arbitrary command execution with the privileges of this process, leading to full host compromise, data theft, or lateral movement.
execSync(instructions, ...) executes task/review-provided instructions as a shell command without warning, sanitization, or allowlisting. Because the instruction source is workflow data rather than trusted code, this is a direct command-injection/arbitrary-code-execution sink on the host environment.
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
{ pattern: /rm\s+-rf\s+\/\s*$/, reason: '删除根目录' },
{ pattern: /rm\s+-rf\s+~\s*$/, reason: '删除用户主目录' },
{ pattern: /rm\s+-rf\s+\/\*/, reason: '删除所有根目录文件' },
{ pattern: /curl\s+[^|]+\|\s*(ba)?sh/, reason: '远程代码执行(curl | sh)' },
{ pattern: /wget\s+[^|]+\|\s*(ba)?sh/, reason: '远程代码执行(wget | sh)' },
{ pattern: /chmod\s+777/, reason: '设置全权限(chmod 777)' },
{ pattern: /\bsudo\b/, reason: '提权操作(sudo)' },
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
{ pattern: /rm\s+-rf\s+~\s*$/, reason: '删除用户主目录' },
{ pattern: /rm\s+-rf\s+\/\*/, reason: '删除所有根目录文件' },
{ pattern: /curl\s+[^|]+\|\s*(ba)?sh/, reason: '远程代码执行(curl | sh)' },
{ pattern: /wget\s+[^|]+\|\s*(ba)?sh/, reason: '远程代码执行(wget | sh)' },
{ pattern: /chmod\s+777/, reason: '设置全权限(chmod 777)' },
{ pattern: /\bsudo\b/, reason: '提权操作(sudo)' },
{ pattern: /dd\s+if=\/dev\/zero/, reason: '磁盘写入操作' },
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
{ pattern: /rm\s+-rf\s+\/\*/, reason: '删除所有根目录文件' },
{ pattern: /curl\s+[^|]+\|\s*(ba)?sh/, reason: '远程代码执行(curl | sh)' },
{ pattern: /wget\s+[^|]+\|\s*(ba)?sh/, reason: '远程代码执行(wget | sh)' },
{ pattern: /chmod\s+777/, reason: '设置全权限(chmod 777)' },
{ pattern: /\bsudo\b/, reason: '提权操作(sudo)' },
{ pattern: /dd\s+if=\/dev\/zero/, reason: '磁盘写入操作' },
{ pattern: /:\(\)\s*\{\s*:\|:&\s*\}\s*;/, reason: 'Fork Bomb' },
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
console.log('用法:');
console.log(' node security-scan.js <task-file.json> # 扫描任务文件');
console.log(' node security-scan.js --stdin # 从 stdin 读取指令');
console.log(' echo "rm -rf /" | node security-scan.js --stdin');
console.log('');
console.log('退出码:');
console.log(' 0 - 安全,无危险命令');
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
console.log('用法:');
console.log(' node security-scan.js <task-file.json> # 扫描任务文件');
console.log(' node security-scan.js --stdin # 从 stdin 读取指令');
console.log(' echo "rm -rf /" | node security-scan.js --stdin');
console.log('');
console.log('退出码:');
console.log(' 0 - 安全,无危险命令');
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
console.log('用法:');
console.log(' node security-scan.js <task-file.json> # 扫描任务文件');
console.log(' node security-scan.js --stdin # 从 stdin 读取指令');
console.log(' echo "rm -rf /" | node security-scan.js --stdin');
console.log('');
console.log('退出码:');
console.log(' 0 - 安全,无危险命令');
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
console.log('用法:');
console.log(' node security-scan.js <task-file.json> # 扫描任务文件');
console.log(' node security-scan.js --stdin # 从 stdin 读取指令');
console.log(' echo "rm -rf /" | node security-scan.js --stdin');
console.log('');
console.log('退出码:');
console.log(' 0 - 安全,无危险命令');
The entire skill documentation, examples, warnings, and operational instructions are presented only in Chinese, with no indication that another language is supported or that the user can opt into this locale. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale constraint is explicitly justified, which is not present here.
At L021, the documentation states a clear intent boundary: TDR is not default behavior and should only trigger when the user says 'use TDR'. However, L049-L064 and L065-L080 describe recommended automatic planning and scheduled heartbeat execution, which operationalize autonomous workflow advancement beyond that stated trigger condition. This is an intent/documentation contradiction rather than mere incompleteness.
The file switches into Chinese at the main description header and continues in Chinese throughout the skill instructions. This imposes a specific language on users without any stated opt-in, alternative language option, or explanation that the skill is intended only for a Chinese-speaking or region-specific context.
The skill documents an automatic execution path that runs tasks based on task configuration without an explicit per-run user approval gate. In the context of a code-writing and file-operating agent workflow, this can enable autonomous modification of files and execution of multi-step actions that the user may not have directly reviewed, increasing the risk of unsafe or unintended changes.
# 自动执行(按任务配置的 flow 字段)
node scripts/auto-execute.js task-001
# 手动指定流程
node scripts/auto-execute.js task-001 --flow full
The manual --flow full invocation still describes a direct execution command for a task in a system designed to generate code, run tests, and perform file operations. Even though this is a CLI example, it normalizes autonomous task execution and could be used to bypass interactive review expectations, especially because the broader skill promotes iterative self-directed execution.
node scripts/auto-execute.js task-001
node scripts/auto-execute.js task-001 --flow full
---
This JSON config uses Chinese-only role/model descriptions and behavior notes throughout, with no indication that users can opt into another language or that the skill is intentionally region-specific. That creates a natural-language locale policy concern because the configuration appears to impose a specific language by default.
The file-level description and usage text are written only in Chinese, and later user-facing status/error messages continue this enforced locale. For a general-purpose script, this is a natural-language locale policy issue because users are not given an English or configurable alternative, and the file does not state that the tool is intentionally limited to a Chinese-speaking environment.
The script deletes a path derived directly from the user-supplied task_id using rm -rf "$lock_dir" without validating that the identifier is constrained to a safe format or that the resolved path remains under the intended tasks directory. An attacker who can supply crafted values such as path traversal segments could potentially cause deletion of arbitrary directories with a .lock.d suffix outside the expected scope, making this a real filesystem safety issue.
The code advertises a substantive audit of instruction adherence, code quality, test validity, and security, but the actual implementation only checks for the presence of task metadata and whether the last execution status was failed. Because it treats successful execution as a proxy for acceptance and performs no real validation of outputs, tests, or generated files, unsafe or incorrect results can be incorrectly approved and moved forward in the workflow.
The header comment describes this script as a 'fully automated' version that automatically calls Sonnet, creates tasks, and starts execution with no human intervention. In reality, planWithSonnet returns a manual handoff object and the main flow instructs the user to copy a prompt into another session and rerun the script, which directly contradicts the documented intent.
The planning prompt explicitly instructs the model to '使用中文描述', which forces a specific language choice. This is a natural-language locale policy issue because the script does not provide opt-in, fallback, or any documented justification that the skill is intended only for a Chinese-language environment.