Back to skill

Security audit

harness

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent long-running task harness, but it gives agents broad automatic control that can reset and clean a repository, run task-supplied commands, and block stopping without enough guardrails.

Install only for dedicated projects or isolated worktrees where repository-wide rollback is acceptable. Keep important work committed or backed up, review harness-tasks.json before runs, do not let untrusted users edit validation or cleanup commands, and disable or remove the hooks if you do not want agents to block stopping or perform post-run self-reflection.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (34)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description presents this skill as a harness for long-running autonomous work: checkpointing progress, recovering from failures, and managing task dependencies across sessions. The supplied code does not implement those capabilities. Instead, it is a post-task hook that activates only when a harness-related marker exists and .harness-reflect is present, then blocks normal completion to inject a self-review prompt. It also reads transcript content and stores per-session counters in temporary files to limit repeated reflection. While it references harness state and is related to a larger harness workflow, this code chunk’s primary purpose is reflective prompting after task completion, not multi-session checkpointing/recovery/dependency management. That is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description says this skill is meant to support multi-session autonomous agent workflows with persistence, recovery, dependency handling, and /harness-based orchestration. The supplied code does not implement that skill behavior. Instead, it is an end-to-end test script that synthesizes a harness-tasks.json file, initializes a repo, calls claude -p with instructions to directly perform 100 file-creation tasks, and then checks completion metrics. Its primary purpose is testing or benchmarking a harness-like workflow, not providing the harness capability itself. It also explicitly disables slash commands, which conflicts with the declared /harness trigger. While the generated task JSON contains fields related to checkpoints and attempts, the script itself does not perform multi-session coordination, failure recovery, or dependency management beyond setting up test data.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
93% confidence
Finding

This example log normalizes use of git reset --hard as a rollback primitive, reinforcing a destructive execution path that can discard legitimate user changes. In an autonomous agent framework, such rollback commands are especially dangerous because they may run repeatedly without contemporaneous human review.

Content

Scanner excerpt · SKILL.md (reported line 54)May include surrounding context.

[2025-07-01T10:15:30Z] [SESSION-1] Completed [task-001] (commit abc1234) [2025-07-01T10:15:31Z] [SESSION-1] Starting [task-002] Add rate limiting (base=abc1234) [2025-07-01T10:20:00Z] [SESSION-1] ERROR [task-002] [TASK_EXEC] Redis connection refused [2025-07-01T10:20:01Z] [SESSION-1] ROLLBACK [task-002] git reset --hard abc1234 [2025-07-01T10:20:02Z] [SESSION-1] STATS tasks_total=5 completed=1 failed=1 pending=3 blocked=0 attempts_total=2 checkpoints=1

text

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The concurrent mode notes that rollback commands can destroy other workers, which confirms the framework is prepared to invoke destructive git operations in shared environments. Even with the warning, the design still permits a parameterized destructive tool path whose safety depends on perfect deployment discipline.

Content

Scanner excerpt · SKILL.md (reported line 197)May include surrounding context.

md
- All workers MUST point at the same state root (the directory that contains `harness-tasks.json`). If you are using separate worktrees/clones, pin it explicitly (e.g., `HARNESS_STATE_ROOT=/abs/path/to/state-root`).
- Task selection is advisory; the real gate is **atomic claim** under the lock: set `status="in_progress"`, set `claimed_by` (stable worker id, e.g., `HARNESS_WORKER_ID`), set `lease_expires_at`. If claim fails (already `in_progress` with a valid lease), pick another eligible task and retry.
- Never run two workers in the same git working directory. Use separate worktrees/clones. Otherwise rollback (`git reset --hard` / `git clean -fd`) will destroy other workers.

## Infinite Loop Protocol

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
97% confidence
Finding

The task execution cycle requires git reset --hard <started_at_commit> and git clean -fd on failure, enabling irreversible deletion of uncommitted and untracked data based on task metadata and runtime state. This is a dangerous tool use pattern because a task failure or manipulated state can trigger destructive repository-wide effects beyond the task's own changes.

Content

Scanner excerpt · SKILL.md (reported line 240)May include surrounding context.

md
- Command exceeds timeout → TIMEOUT
4. **Record outcome**:
   - **Success**: status=`completed`, set `completed_at`, log `Completed [<task-id>] (commit <hash>)`, git commit
   - **Failure**: increment `attempts`, append error to `error_log`. Verify `started_at_commit` exists via `git cat-file -t <hash>` — if missing, mark failed at max_attempts. Otherwise execute `git reset --hard <started_at_commit>` and `git clean -fd` to rollback ALL commits and remove untracked files. Execute `on_failure.cleanup` if defined. Log `ERROR [<task-id>] [<category>] <message>`. Set status=`failed` (Task Selection Algorithm pass 2 handles retries when attempts < max_attempts)
5. **Track**: Increment per-session task counter. If `max_tasks_per_session` reached, log STATS and STOP.
6. **Continue**: Immediately pick next task (zero idle time)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
94% confidence
Finding

The recovery matrix instructs the agent to hard reset to a prior commit if validation fails during interrupted-task recovery. Recovery logic runs at session start, so a stale or incorrect state assessment could automatically erase work from a previous session or a user.

Content

Scanner excerpt · SKILL.md (reported line 272)May include surrounding context.

md
|---|---|---|---|
| No | No | None | Mark `failed` with `[SESSION_TIMEOUT] No progress detected`, increment attempts |
| No | No | Some | Verify file state matches checkpoint claims. If files reflect checkpoint progress, resume from last step. If not, mark `failed` — work was lost |
| No | Yes | Any | Run `validation.command`. If passes → mark `completed`. If fails → `git reset --hard <started_at_commit>`, mark `failed` |
| Yes | No | Any | Run validation WITH uncommitted changes present. If passes → commit, mark `completed`. If fails → `git reset --hard <started_at_commit>` + `git clean -fd`, mark `failed` |
| Yes | Yes | Any | Commit uncommitted changes, run `validation.command`. If passes → mark `completed`. If fails → `git reset --hard <started_at_commit>` + `git clean -fd`, mark `failed` |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

This recovery branch compounds the risk by combining validation with uncommitted changes and then performing git reset --hard plus git clean -fd on failure. That path can erase both tracked and untracked work during an automated resume flow, making accidental data loss likely in realistic operator usage.

Content

Scanner excerpt · SKILL.md (reported line 273)May include surrounding context.

md
| No | No | None | Mark `failed` with `[SESSION_TIMEOUT] No progress detected`, increment attempts |
| No | No | Some | Verify file state matches checkpoint claims. If files reflect checkpoint progress, resume from last step. If not, mark `failed` — work was lost |
| No | Yes | Any | Run `validation.command`. If passes → mark `completed`. If fails → `git reset --hard <started_at_commit>`, mark `failed` |
| Yes | No | Any | Run validation WITH uncommitted changes present. If passes → commit, mark `completed`. If fails → `git reset --hard <started_at_commit>` + `git clean -fd`, mark `failed` |
| Yes | Yes | Any | Commit uncommitted changes, run `validation.command`. If passes → mark `completed`. If fails → `git reset --hard <started_at_commit>` + `git clean -fd`, mark `failed` |

4. **Log recovery**: `[timestamp] [SESSION-N] RECOVERY [task-id] action="<action taken>" reason="<reason>"`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

The second recovery branch again authorizes reset-and-clean after committing uncommitted changes, which can still destroy newly created files and revert broader repository state if validation fails. The autonomous context makes this more dangerous because the agent may decide this without the user's immediate awareness.

Content

Scanner excerpt · SKILL.md (reported line 274)May include surrounding context.

md
| No | No | Some | Verify file state matches checkpoint claims. If files reflect checkpoint progress, resume from last step. If not, mark `failed` — work was lost |
| No | Yes | Any | Run `validation.command`. If passes → mark `completed`. If fails → `git reset --hard <started_at_commit>`, mark `failed` |
| Yes | No | Any | Run validation WITH uncommitted changes present. If passes → commit, mark `completed`. If fails → `git reset --hard <started_at_commit>` + `git clean -fd`, mark `failed` |
| Yes | Yes | Any | Commit uncommitted changes, run `validation.command`. If passes → mark `completed`. If fails → `git reset --hard <started_at_commit>` + `git clean -fd`, mark `failed` |

4. **Log recovery**: `[timestamp] [SESSION-N] RECOVERY [task-id] action="<action taken>" reason="<reason>"`

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The error-handling table codifies git reset --hard <started_at_commit> as the default response to task execution failures. Turning destructive repository rollback into a routine control-flow action materially increases the blast radius of ordinary errors and of any maliciously induced failure condition.

Content

Scanner excerpt · SKILL.md (reported line 286)May include surrounding context.

md
|----------|-----------------|--------------|
| `ENV_SETUP` | Re-run init, then STOP if still failing | Run `harness-init.sh` again immediately. If fails twice, log and stop — environment is broken |
| `CONFIG` | STOP (requires human fix) | Log the config error precisely (file + field), then STOP. Do not guess or auto-mutate task metadata |
| `TASK_EXEC` | Rollback via `git reset --hard <started_at_commit>`, retry | Verify `started_at_commit` exists (`git cat-file -t <hash>`). If missing, mark failed at max_attempts. Otherwise reset, run `on_failure.cleanup` if defined, retry if attempts < max_attempts |
| `TEST_FAIL` | Rollback via `git reset --hard <started_at_commit>`, retry | Reset to `started_at_commit`, analyze test output to identify fix, retry with targeted changes |
| `TIMEOUT` | Kill process, execute cleanup, retry | Wrap validation with `timeout <seconds> <command>`. On timeout, run `on_failure.cleanup`, retry (consider splitting task if repeated) |
| `DEPENDENCY` | Skip task, mark blocked | Log which dependency failed, mark task as `failed` with dependency reason |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

The same table makes hard reset the default for test failures as well, meaning even benign failing tests can trigger irreversible repository rewinds. This is dangerous because test failures are common and can be intentionally induced, creating an easy path to repeated data-destructive actions.

Content

Scanner excerpt · SKILL.md (reported line 287)May include surrounding context.

md
| `ENV_SETUP` | Re-run init, then STOP if still failing | Run `harness-init.sh` again immediately. If fails twice, log and stop — environment is broken |
| `CONFIG` | STOP (requires human fix) | Log the config error precisely (file + field), then STOP. Do not guess or auto-mutate task metadata |
| `TASK_EXEC` | Rollback via `git reset --hard <started_at_commit>`, retry | Verify `started_at_commit` exists (`git cat-file -t <hash>`). If missing, mark failed at max_attempts. Otherwise reset, run `on_failure.cleanup` if defined, retry if attempts < max_attempts |
| `TEST_FAIL` | Rollback via `git reset --hard <started_at_commit>`, retry | Reset to `started_at_commit`, analyze test output to identify fix, retry with targeted changes |
| `TIMEOUT` | Kill process, execute cleanup, retry | Wrap validation with `timeout <seconds> <command>`. On timeout, run `on_failure.cleanup`, retry (consider splitting task if repeated) |
| `DEPENDENCY` | Skip task, mark blocked | Log which dependency failed, mark task as `failed` with dependency reason |
| `SESSION_TIMEOUT` | Use Context Window Recovery Protocol | New session assesses partial progress via Recovery Protocol — may result in completion or failure depending on validation |

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · tests/e2e-100tasks.sh (reported line 105)May include surrounding context.

sh
unset CLAUDECODE
REFLECT_MAX_ITERATIONS=5 \
HARNESS_STATE_ROOT="${PROJECT_DIR}" \
claude -p "${PROMPT}" \
  --model sonnet \
  --dangerously-skip-permissions \
  --disable-slash-commands \

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · tests/test_hooks.py (reported line 26)May include surrounding context.

python
def build_hook_env(env_extra: dict | None = None) -> dict[str, str]:
    """Build an isolated environment for hook subprocesses."""
    env = os.environ.copy()
    # Clear harness env vars to avoid interference
    env.pop("HARNESS_STATE_ROOT", None)
    env.pop("HARNESS_WORKER_ID", None)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill describes file, environment, and shell-capable operations but does not declare an explicit tool scope or permission boundary. For a long-running autonomous harness that modifies git state and executes commands, missing scope declarations increases the chance of over-privileged execution and unsafe operator assumptions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The skill is explicitly designed for cross-session persistence, maintaining progress files and resumable state over many sessions. Persistence is core to the harness purpose, but it also creates a durable state channel that can carry sensitive task context, amplify mistakes across sessions, and be tampered with to influence future autonomous behavior.

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

/harness init # Initialize harness files in project /harness run # Start/resume the infinite loop /harness status # Show current progress and stats /harness add "task description" # Add a task to the list

text

## Activation Marker

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs the agent to execute task-supplied validation commands and failure cleanup hooks directly from mutable task metadata. That creates a command-injection and unsafe-execution surface where anyone who can modify harness-tasks.json can cause arbitrary shell execution under the agent's privileges.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The protocol explicitly directs destructive rollback operations using git reset --hard and git clean -fd, which can irreversibly delete uncommitted and untracked user work. Because this is an autonomous long-running skill, lack of a strong warning and consent gate materially increases the risk of accidental data loss.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The hook emits operational warnings and blocking reasons in Chinese, including recovery instructions, regardless of user locale. This is a natural-language policy issue because the file does not offer a language choice or document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The main blocking summary and required follow-up instructions are emitted in Chinese only, which can force a specific language on users. No opt-in, fallback, or documented region-specific scope is present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

This Python file contains natural-language strings shown to users when a stop is blocked, and those messages are forced to Chinese. The policy explicitly flags language or locale constraints when the skill does not offer user opt-in or document a justified regional limitation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

These lines emit a second stop-blocking message entirely in Chinese, again imposing a specific language on users. Because the file provides no alternative locale handling or documented justification, this matches the natural-language policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This Python file includes a stderr message written only in Chinese, with no indication that users can choose their language or that the hook is intended solely for a Chinese-language environment. That creates a natural-language policy concern because the skill imposes a specific locale on users without opt-in.

Content

No source excerpt is available for this finding.

Bundled hooks can execute when matching lifecycle events occur.

Medium
Category
Bundled Execution Surface
Confidence
95% confidence
Finding

This skill registers multiple lifecycle hooks that automatically execute local Python commands on Stop, SessionStart, TeammateIdle, and SubagentStop events. Even though the JSON itself only wires up scripts rather than containing the script bodies, automatic hook-triggered command execution expands the attack surface and can run code without an explicit user action at the time of execution; in a long-running autonomous harness, that makes unintended behavior or abuse more dangerous.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's docstring and all injected self-reflection prompt text are written in Chinese, which effectively enforces a specific language for user-visible behavior. There is no indication in this file that the user chose this locale or that the skill is intentionally restricted to a Chinese-language context.

Content

No source excerpt is available for this finding.

Tainted flow: 'p' from os.environ.get (line 53, credential/environment) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · hooks/self-reflect-stop.py (reported line 95)May include surrounding context.

python
def _write_counter(session_id: str, count: int) -> None:
    p = _counter_path(session_id)
    try:
        p.write_text(str(count), encoding="utf-8")
    except Exception:
        pass

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This hook reads the transcript file to extract the original user prompt and also writes a per-session counter to the system temp directory. In this file, those data-affecting operations are not accompanied by any confirmation prompt, user-facing log/print disclosure, or explicit warning that user conversation content and session metadata are being read and persisted.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.