Back to skill

Security audit

Iterate

Security checks across malware telemetry and agentic risk

Overview

The skill is not plainly malicious, but it needs review because its high-autonomy code and Git workflow has conflicting instructions that could publish changes unexpectedly, and its docs include an unsafe curl-to-bash install path.

Install only if you are comfortable with an autonomous coding skill that can edit files, run configured validation commands, and use git. Before use, treat merge and push as manual steps regardless of the current docs, review any generated commits before publishing, avoid the documented curl-to-bash harness install path, and keep secrets out of personalization notes and project context files.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
README.md:81
Finding
Mutable Remote Installation Script Is Piped Directly into Bash<![CDATA[ ## Vulnerability Details **File Location**: `README.md:81-83` **Vulnerability Type**: Remote payload retrieval and immediate execution **Risk Level**: Critical ### Vulnerable Code ```bash # or script install (oh / ohmo have fully migrated to ih) curl -fsSL https://raw.githubusercontent.com/jingzhao-l/iterate-harness/main/scripts/install.sh | bash ih iterate init && ih iterate review ``` ### Technical Analysis The documented installation command retrieves a shell script from the mutable `main` branch of a separate GitHub repository and sends the response directly to `bash`. The script is neither pinned to an immutable commit nor verified using a checksum or cryptographic signature before execution. This execution model prevents the user from reviewing the downloaded content before it runs. It also bypasses the mandatory SHA-256 verification controls implemented by this project's Python and npm installers. The effective payload can change after this Skill has been reviewed or published. Although HTTPS protects the connection in transit under normal conditions, it does not protect against compromise of the referenced GitHub account, repository, branch, or release process. It also does not establish that the fetched script is the same script that was audited. ### Attack Path 1. An attacker compromises the `jingzhao-l/iterate-harness` repository, its maintainer account, or a workflow capable of modifying `main`. 2. The attacker replaces or modifies `scripts/install.sh` with commands that perform arbitrary local actions. 3. A user follows the installation command in the README. 4. `curl` retrieves the attacker-controlled script from the mutable branch. 5. The pipe sends the response directly to `bash`, without local inspection or integrity verification. 6. The malicious commands execute with the privileges of the user running the installation command. ### Impact Assessment Successful exploitation provides arbitrary command execution under the in ...[truncated 687 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `curl | bash` installation pattern from all documentation, including translated README files. 2. Prefer the documented, versioned npm installer where its package publication and integrity controls are maintained. 3. If a shell installer remains necessary: - Publish it as a versioned release asset. - Pin the download to a specific immutable version or commit. - Download the file to disk rather than piping it into a shell. - Publish a SHA-256 digest through an independently authenticated channel. - Verify the digest before execution. - Display the script path and encourage inspection before running it. 4. Prefer cryptographic release signatures or provenance attestations in addition to SHA-256 checksums. 5. Ensure the checksum or signature is not obtained solely from the same mutable location as the payload. 6. Update the equivalent command in `README.zh-CN.md` so that all supported documentation follows the same secure installation procedure. A safer workflow should follow this sequence: ```bash curl -fL -o install.sh https://example.invalid/releases/download/vX.Y.Z/install.sh printf '%s %s\n' '<independently-published-sha256>' install.sh | sha256sum -c - less install.sh bash install.sh ``` The real URL, version, and digest must be immutable and publisher-controlled. ]]>

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:835
Finding
Disabled Push Setting Still Instructs the Agent to Push at Session End<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:835-845` **Vulnerability Type**: Contradictory Skill instructions causing unauthorized repository publication **Risk Level**: High ### Vulnerable Instructions ```text 4. Push / Push ⚠️ High-risk action - Secure by default: git.push_per_round defaults to false, meaning it does not automatically push. - Risk notice: If automatic push is enabled, it will become externally visible immediately, and subsequent rounds will continue iterating based on the pushed state. It is recommended to keep push_per_round: false and push only once at the end of the session. - If git.push_per_round is true: - git push origin {target_branch} - If rejected, first git pull --rebase, resolve conflicts, validate again, and then push. - Limit the push-pull-rebase loop to three attempts; if it still fails, stop and ask the user to handle it manually. - Never force-push to main/master. - If git.push_per_round is false (default): - Do not push during this round; retain only the local merge. If auto_merge is also false, retain changes only on the iteration branch. - At the final round or session end, run git push origin {target_branch} once; follow the same three-attempt limit. ``` The quoted English rendering preserves the operative meaning of the bilingual instructions in `SKILL.md`. ### Technical Analysis The Skill repeatedly represents `git.push_per_round=false` as a secure, opt-in default. However, the branch that handles this disabled setting still directs the Agent to execute `git push origin {target_branch}` at the final round or end of the session. This means the setting changes only the timing of the network operation rather than disabling it. The behavior contradicts the manifest's stated security model and the surrounding documentation that says push operations are opt-in. A repository review and local repair workflow does not require publishing commits to a remote. T ...[truncated 1645 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change the disabled branch so that `git.push_per_round=false` prohibits every automatic push, including end-of-session pushes. 2. Require explicit user confirmation immediately before each push, showing: - Remote name and URL. - Local source branch. - Remote destination branch. - Commits that will be transmitted. 3. If end-of-session pushing is desired, introduce a separate setting such as: ```yaml git: push_per_round: false push_at_end: false ``` Both settings should default to `false`. 4. Do not infer push authorization from permission to edit, commit, merge, or run the Skill. 5. Ensure non-interactive execution fails closed when no explicit push authorization is available. 6. Add regression tests asserting that no `git push` command is issued when both push settings are disabled. 7. Update all README files, templates, examples, and assistant-specific Skill variants to use identical opt-in semantics. 8. At session completion, report the local branch and provide a suggested push command instead of executing it: ```bash git push origin <iteration-branch> ``` The user can then review and run the command manually. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if not _command_is_safe(command):
        return EXIT_FAIL, f"refused: unsafe command {command!r} (shell metacharacter or empty)"
    try:
        proc = subprocess.run(
            command,
            cwd=str(project_root),
            shell=True,
Confidence
91% confidence
Finding
The code executes configured command strings via `subprocess.run(..., shell=True)`, which is inherently dangerous because shell parsing expands the attack surface beyond simple metacharacter checks. Although the code attempts to restrict commands with `_command_is_safe`, the safety of execution now depends entirely on the completeness and correctness of an external allowlist/validator; any bypass, parser gap, or future drift can lead to arbitrary command execution in the project context.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The git workflow example normalizes merge/push steps as part of the standard per-round flow, even though other sections say merge and push are opt-in and disabled by default. In a high-autonomy coding skill with shell and git permissions, contradictory operational guidance can cause an agent or human operator to perform unintended repository mutations or remote publication.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
Review-only mode promises it will never modify files, but later states it may still write a report record to `.iterate_decisions.md`. That contradiction weakens a core safety guarantee: users may invoke read-only mode specifically to avoid workspace mutation, yet the documented behavior still permits writes.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The skill documentation introduces onboarding via terminal command and 'AI auto-scan' behavior that is not mapped to the declared Claude Code tool operations, creating an implicit execution path outside the documented control surface. In a skill intended for automated code iteration, undocumented cross-channel behavior can cause users or agents to perform additional actions with weaker reviewability and fewer safety guarantees.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Documenting an installer/update path through terminal commands expands the skill beyond its stated code-iteration purpose and encourages users to execute external setup flows. That broadens the trust boundary and can be abused to introduce unreviewed code, configuration changes, or persistence mechanisms under the guise of onboarding or updates.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The show command explicitly renders full personalization content, including free-form notes, conventions, risk areas, known intentional exceptions, and extra validation commands, and it also emits the same data in JSON mode. Those fields can easily contain sensitive operational details, internal paths, security exceptions, or secrets copied into notes, so displaying them without any warning, redaction, or scoped output creates an information exposure risk, especially in CI logs, screen sharing, or shared terminals.

External Script Fetching

Low
Category
Supply Chain
Content
npm install -g iterate-harness

# or script install (oh / ohmo have fully migrated to ih)
curl -fsSL https://raw.githubusercontent.com/jingzhao-l/iterate-harness/main/scripts/install.sh | bash
ih iterate init && ih iterate review

# iterate-plugin: GitHub install for the dsh desktop plugin
Confidence
97% confidence
Finding
The README recommends `curl -fsSL ... | bash` to fetch and immediately execute a remote script from GitHub. Even though this is for a related component, it creates a direct remote-code-execution path if the source repository, network path, or referenced branch content is compromised, and users are trained to run it without independent review or pinned integrity verification.

External Script Fetching

Low
Category
Supply Chain
Content
npm install -g iterate-harness

# 或脚本安装(oh / ohmo 已全面迁移为 ih)
curl -fsSL https://raw.githubusercontent.com/jingzhao-l/iterate-harness/main/scripts/install.sh | bash
ih iterate init && ih iterate review

# iterate-plugin:dsh 桌面插件的 GitHub 安装
Confidence
97% confidence
Finding
The README recommends fetching a remote shell script and piping it directly to bash. This is dangerous because any compromise of the GitHub account, repository, branch, CDN path, or network trust chain can turn installation into immediate arbitrary code execution on the user's machine, and unlike the later installer flow, this path does not mention checksum verification.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
| 项 | 设计 |
|---|---|
| 存储 | `.iterate/findings-triage.jsonl` append-only 日志,镜像 `security.AuditLog` 模式;`(file, line, dimension)` 去重键,**最新一条生效**(重复分诊只追加不改写历史) |
| 端点 | `GET /runs/findings/triage`(全部决策,最近优先)、`POST /runs/findings/triage`(记录,需 `confirm=true` + 审计)、`DELETE /runs/findings/triage`(清除全部,需 `confirm=true` + 审计) |
| 请求模型 | `FindingsTriageRequest{file, line?, dimension, decision: "approve"|"reject", note?}`(decision 用 `Literal` 限定) |
| 健壮性 | 读取对损坏行防御(跳过非 JSON / 非 dict / 空 key);写入 best-effort 永不抛;非法 decision 抛 `ValueError` |
| 语义 | `approve`=同意该 finding / 接受其修复建议;`reject`=误报 / 跳过修复。与 §18 引擎暂停菜单的审批互补:这是**人类对历史 run 的持久记录**,引擎审批是**进行中 run 的实时决策** |
Confidence
83% confidence
Finding
A bulk-delete endpoint for findings triage state can be dangerous because a single request can erase audit-relevant review decisions and suppress historical context. The design mentions `confirm=true` and audit logging, but it does not mention authentication/authorization or stronger anti-automation controls at this endpoint, so if the local WebUI trust boundary is crossed, state tampering or destructive cleanup becomes easy.

Chaining Abuse

High
Category
Tool Misuse
Content
npm install -g iterate-harness

# or script install (oh / ohmo have fully migrated to ih)
curl -fsSL https://raw.githubusercontent.com/jingzhao-l/iterate-harness/main/scripts/install.sh | bash
ih iterate init && ih iterate review

# iterate-plugin: GitHub install for the dsh desktop plugin
Confidence
98% confidence
Finding
The `| bash` construct chains network retrieval directly into shell execution, removing any opportunity for integrity checks, code review, or safe failure boundaries. In the context of an AI-assistant skill ecosystem that encourages automation and installation, this pattern is more dangerous because users may copy-paste commands verbatim, turning any upstream compromise into immediate code execution on the host.

Chaining Abuse

High
Category
Tool Misuse
Content
npm install -g iterate-harness

# 或脚本安装(oh / ohmo 已全面迁移为 ih)
curl -fsSL https://raw.githubusercontent.com/jingzhao-l/iterate-harness/main/scripts/install.sh | bash
ih iterate init && ih iterate review

# iterate-plugin:dsh 桌面插件的 GitHub 安装
Confidence
98% confidence
Finding
The '| bash' pattern creates an immediate command-execution chain from untrusted remote content to the local shell. In the context of an AI skill ecosystem that encourages automation, this is especially risky because users may copy-paste it without review, giving an attacker a one-step path to execute arbitrary commands.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- Fail-closed metachar enforcement: a command containing shell-chaining
  metacharacters (or empty after trim) is REFUSED at execution time — and
  flagged by ``pre-check`` / ``--dry-run`` — so a hand-edited or drift-polluted
  config can never chain extra shell through ``subprocess.run(..., shell=True)``.
- ``--dry-run`` prints the exact commands that WOULD run without executing them
  (fail-fast: unsafe commands are reported as failures, not run).
"""
Confidence
88% confidence
Finding
This finding points to the documented design choice of routing configured commands through `subprocess.run(..., shell=True)`. In a tool that reads commands from project configuration and advertises automated execution, using the shell materially increases the chance that configuration poisoning, validator bypasses, or future code changes become arbitrary command execution.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
#: doctor.COMMAND_METACHARS / scripts/validate.py (kept in sync by
#: tests/test_validate.py). Enforced fail-closed at execution time so a
#: hand-edited or drift-polluted config can never smuggle chained commands into
#: ``subprocess.run(..., shell=True)``.
COMMAND_METACHARS: frozenset[str] = frozenset(FORBIDDEN_COMMAND_CHARS)
Confidence
88% confidence
Finding
This finding reflects the same underlying issue: the module’s threat model assumes metacharacter filtering is sufficient to make `shell=True` safe. In practice, shell execution remains fragile because security depends on a blacklist, synchronized constants, and external validator behavior, any of which can drift or be bypassed over time.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
(``personalize._is_known_safe_command``), so a hand-edited or
    drift-polluted config that bypasses the wizard cannot smuggle
    metachar-free but arbitrary executables (``rm -rf .``, ``curl ...``) into
    ``subprocess.run(..., shell=True)``.
    """
    if not command.strip() or any(ch in COMMAND_METACHARS for ch in command):
        return False
Confidence
90% confidence
Finding
The code explicitly relies on `_is_known_safe_command` to permit metachar-free commands and then sends them to a shell. In the context of an automated coding assistant skill, that is more dangerous than normal because project configuration is an attacker-reachable control plane: if an adversary can influence config content or the validator logic, they can turn the guard feature into command execution on the host.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
npm-installer/lib/installer.js:154