Back to skill

Security audit

Autonomous Skill

Security checks for vulnerabilities and agentic risk

Overview

This skill is designed for autonomous work, but it gives unattended child agents broad default authority and persistent loop behavior that users should review carefully before installing.

Review this skill before installing. Use it only in isolated workspaces, set explicit max session or iteration limits, avoid bypassPermissions unless you intentionally want unattended broad access, and expect local task logs/transcripts under .autonomous plus hook state under .claude. Do not run it on untrusted prompts or repositories without sandboxing.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/run-session.sh:26
Finding

Autonomous headless sessions bypass permission checks by default

Content
View full analysis
/dev/null || true ``` ```bash build_claude_args() { local -a args=() args+=(--output-format stream-json --verbose) args+=(--model "$opt_model") args+=(--effort "$opt_effort") args+=(--max-budget-usd "$opt_max_budget") args+=(--permission-mode "$opt_permission_mode") args+=(--no-session-persistence) [ -n "$opt_fallback_model" ] && args+=(--fallback-model "$opt_fallback_model") [ -n "$opt_add_dir" ] && args+=(--add-dir "$opt_add_dir") echo "${args[@]}" } ``` ### Technical Analysis The headless runner defaults to Claude Code's `bypassPermissions` mode. This removes interactive authorization checks from autonomous tool operations rather than requiring users to opt into that behavior explicitly. The script also unsets `CLAUDECODE`, which disables the environment-based protection that ordinarily prevents a Claude Code process from launching another nested Claude Code session. Each resulting child session may receive up to 100 turns, and the outer session loop is unlimited unless the caller explicitly supplies a limit. These behaviors combine to create an execution environment in which task instructions can cause commands and file operations to run repeatedly without user approval. This is especially dangerous when the task incorporates untrusted repository content, issue descriptions, generated tracking files, or other prompt-injection-capable material. The documented behavior is inconsistent with the implementation: `SKI ...[truncated 1849 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup-loop.sh:51
Finding

Unvalidated task name permits filesystem path traversal in hook setup

Content
View full analysis
&2; exit 1; } TASK_NAME="$2"; shift 2 ;; ``` ```bash # Generate task name if not provided if [[ -z "$TASK_NAME" ]]; then TASK_NAME=$(echo "$PROMPT" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | cut -c1-30 | sed 's/^-//' | sed 's/-$//') [[ -z "$TASK_NAME" ]] && TASK_NAME="task-$(date +%Y%m%d-%H%M%S)" fi TASK_DIR=".autonomous/$TASK_NAME" # Set up task directory for structured mode if [[ "$MODE" == "structured" ]]; then mkdir -p "$TASK_DIR/sessions" fi ``` ### Technical Analysis An explicitly supplied `--task-name` is accepted without validating path separators, `..` components, control characters, or an allowlisted name format. The value is directly concatenated with `.autonomous/` and then used as a filesystem path. For example, a task name such as `../../outside-target` makes `TASK_DIR` resolve outside the intended `.autonomous` tracking directory. In structured mode, the script immediately creates the resulting directory hierarchy with `mkdir -p`. The unsafe path is also written into `.claude/autonomous-loop.local.md`. The Stop hook later trusts the stored `task_dir` value when checking `task_list.md` and reporting progress. This extends the effect beyond initial directory creation and causes later hook activity to reference an attacker-selected location. The headless runner contains a `validate_task_name` function, but equivalent validation is missing from `setup-loop.sh`. ### Attack Path 1. An attacker or unsafe wrapper supplies a crafted argument such as: ```bash bash scripts/setup-loop.sh "Perform task" \ --mode structured \ --task-name ../../outside-target ``` 2. The script a ...[truncated 1285 chars]
Remediation
View remediation
&2 exit 1 fi ``` 3. Reject `..`, `/`, `\`, whitespace, newlines, leading hyphens, and control characters. 4. Resolve the canonical `.autonomous` root and candidate task path, then verify the candidate remains beneath the root before creating directories. 5. Use `mkdir -- "$TASK_DIR/sessions"` after validation to terminate option parsing defensively. 6. Validate the `task_dir` field again in `stop-hook.sh`; do not trust the persisted state file merely because this setup script created it. 7. Add regression tests covering absolute paths, traversal paths, encoded separators, newlines, and leading-hyphen names. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup-loop.sh:44
Finding

Unescaped arguments allow hook-state frontmatter injection and corruption

Content
View full analysis
&2; exit 1; } MAX_ITERATIONS="$2"; shift 2 ;; --completion-promise) [[ -z "${2:-}" ]] && { echo "Error: --completion-promise requires text" >&2; exit 1; } COMPLETION_PROMISE="$2"; shift 2 ;; --mode) [[ -z "${2:-}" ]] && { echo "Error: --mode requires structured or lightweight" >&2; exit 1; } MODE="$2"; shift 2 ;; --task-name) [[ -z "${2:-}" ]] && { echo "Error: --task-name requires a name" >&2; exit 1; } TASK_NAME="$2"; shift 2 ;; ``` ```bash # Quote values for YAML if [[ -n "$COMPLETION_PROMISE" ]]; then PROMISE_YAML="\"$COMPLETION_PROMISE\"" else PROMISE_YAML="null" fi cat > .claude/autonomous-loop.local.md <
Remediation
View remediation
.claude/autonomous-loop.local.json ``` 4. Parse the state with `jq` and reject missing, duplicate, malformed, or incorrectly typed values. 5. Treat the state file as untrusted inside `stop-hook.sh`; revalidate numeric ranges, enums, safe paths, and string lengths before use. 6. Store the prompt separately from structured control state so that prompt delimiters cannot alter configuration parsing. 7. Create the state file with restrictive permissions and an atomic temporary-file replacement. 8. Add tests for embedded quotes, multiline strings, duplicate keys, frontmatter delimiters, invalid modes, and nonnumeric iteration limits. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

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).

Content

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

md
`.claude/autonomous-loop.local.md` and blocks exit until the promise is detected
or max iterations reached.

To cancel an active hook-mode loop: `rm .claude/autonomous-loop.local.md`

## Workflow Detail

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

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).

Content

Scanner excerpt · scripts/run-session.sh (reported line 155)May include surrounding context.

sh
release_lock() {
    local task_dir="$1"
    rm -f "$task_dir/run.lock"
}

# ── Promise detection ─────────────────────────────────────────────────

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 · scripts/run-session.sh (reported line 287)May include surrounding context.

sh
claude_args=$(build_claude_args)

    local exit_code=0
    claude -p "Task: $task_desc
Task Name: $task_name
Task Directory: $task_dir
Completion Promise: $opt_completion_promise

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 · scripts/run-session.sh (reported line 323)May include surrounding context.

sh
claude_args=$(build_claude_args)

    local exit_code=0
    claude -p "Continue working on the task.
Task Name: $task_name
Task Directory: $task_dir
Completion Promise: $opt_completion_promise

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 · scripts/run-session.sh (reported line 360)May include surrounding context.

sh
claude_args=$(build_claude_args)

    local exit_code=0
    claude -p "$task_desc

---
You are in iteration $session_num of an iterative development loop.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
88% confidence
Finding

This script writes directly into the agent configuration directory by creating .claude/autonomous-loop.local.md, which can alter agent behavior for the current repository or session. In the context of an autonomous, long-running skill, this is especially sensitive because the file enables persistent loop state and can influence future agent execution without additional user confirmation.

Content

Scanner excerpt · scripts/setup-loop.sh (reported line 95)May include surrounding context.

sh
PROMISE_YAML="null"
fi

cat > .claude/autonomous-loop.local.md <<EOF
---
active: true
iteration: 1

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The invocation guidance uses broad phrases like "keep working on this," "batch process," and "iterate until done," which can match many ordinary user requests and cause the skill to activate in situations where unattended execution was not explicitly intended. In this skill's context, that increases the chance of autonomous background actions, repeated sessions, and persistent logging being initiated without sufficiently informed user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill describes headless mode operationally but does not clearly warn that it spawns unattended child sessions and writes persistent state and transcript logs under project directories. In an autonomous-execution skill, omission of that warning is safety-relevant because users may unknowingly allow background actions and storage of potentially sensitive task content.

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 hook configuration causes a shell command to execute automatically on the Stop lifecycle event, which creates an implicit code-execution path whenever the skill is installed and used. Because the command points to a bundled script within the skill package, any malicious or unsafe logic in that script would run without an additional explicit user review at trigger time, making this a real execution-surface risk rather than a false positive.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script defaults Claude Code to bypassPermissions, which grants the autonomous agent elevated access without requiring the user to explicitly opt in. In a long-running autonomous skill, that meaningfully increases the blast radius of prompt injection, task abuse, or accidental destructive actions because the agent can act without normal approval gates.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script performs autonomous shell-driven model execution with a permissive default permission mode and no meaningful user-facing warning at runtime. Users may invoke it expecting ordinary task automation, while the agent actually runs with elevated privileges that can modify files or access more data than necessary.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script intentionally unsets the CLAUDECODE guard so it can launch nested headless sessions from inside an interactive Claude Code session. That bypasses a safety boundary designed to prevent recursive or unattended agent spawning, making it easier for untrusted task content to escalate into additional autonomous executions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This hook performs file deletion of the autonomous loop state file as part of several control paths, including corruption handling and normal stop conditions. Although some paths print status messages, there is no user confirmation before removing the file, and the deletion behavior is not otherwise disclosed in this file beyond implementation comments.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.