Back to skill

Security audit

Agent Swarm Orchestrator

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed coding-automation skill, but it gives background agents broad power to change, publish, and merge code with weak safeguards.

Install only if you intentionally want a background coding orchestrator with access to your Git provider, Claude/Codex sessions, local repos, Obsidian notes, and notification targets. Use an isolated OS account and disposable worktrees, remove dangerous sandbox/permission-bypass flags, require explicit confirmation before pushes and merges, avoid automatic npm lifecycle scripts, and do not point it at shared or untrusted Obsidian folders until the Python interpolation issues are fixed.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T01 · Skill Instruction Hijacking

Error
Location
scripts/config.sh:147
Finding

Untrusted Obsidian Content Is Passed to Coding Agents with Security Controls Disabled

Content
View full analysis
\s*(.+)$', block) if not desc_lines: print(f" Skip task (no description): {task_name}") continue task_desc = "\n".join(line.strip() for line in desc_lines) ``` ```python result = subprocess.run([ os.path.join(scripts_dir, 'spawn-agent.sh'), project, task_desc, '', 'normal', task_name, note_file, dedup_key ], capture_output=True, text=True) ``` ```bash { echo "You are working on project: ${PROJECT_NAME}" echo "Task: ${TASK_DESCRIPTION}" echo "Priority: ${PRIORITY}" echo "Working directory: ${WORKTREE}" echo "Branch: ${BRANCH_NAME}" echo "" echo "--- PROJECT CONTEXT ---" echo "${CONTEXT_SECTION}" echo "--- END CONTEXT ---" echo "" echo "Instructions:" echo "1. Read existing code carefully before making changes" echo "2. Follow existing code style and architecture" echo "3. Make clean atomic commits with clear messages" echo "4. When done: push branch to origin" echo "5. Do NOT create MR/PR — that will be handled automatically after review" echo "6. Run tests if available" echo "7. Definition of done: code committed + pushed to origin" echo "8. After completing all work, summarize what you did." echo "9. If your changes introduce new features, gameplay changes, new modules, architecture changes, or add key files, update context.md (${CONTEXT_PATH}) in the project root accordingly. Only skip for trivial config/formatting changes." echo "" echo "Start working now." } > "$PROMPT_FILE" ``` ```bash swarm_run_coding_agent() { local prompt="$1" log_file="$2" case "$SWARM_CODING_AGENT" in claude) claude --dangero ...[truncated 2318 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan-obsidian.sh:32
Finding

Arbitrary Python Execution Through Crafted Obsidian Note Filenames

Content
View full analysis
> "$SCAN_LOG" 2>&1 import os, re, subprocess, hashlib note_file = r'''$NOTE_FILE''' project = r'''$PROJECT''' scripts_dir = r'''$SCRIPTS_DIR''' logs_dir = r'''$LOGS_DIR''' content = open(note_file, 'r', encoding='utf-8').read() ``` ### Technical Analysis The heredoc delimiter is unquoted, so the shell expands `$NOTE_FILE`, `$PROJECT`, `$SCRIPTS_DIR`, and `$LOGS_DIR` before Python parses the program. In particular, `$NOTE_FILE` and `$PROJECT` are derived from filesystem names found under the configured Obsidian directory. Although the values are surrounded by Python raw triple-quoted strings, a filename containing `'''` can terminate the string literal. Additional Python statements in the filename can then become executable source code. Shell quoting around the earlier `find` loop does not protect against this second-stage Python source injection. ### Attack Path 1. An attacker gains the ability to create or rename a Markdown file in the configured Obsidian directory. 2. The attacker chooses a filename containing a triple-quote terminator and syntactically valid Python statements. 3. The scheduled scanner discovers the maliciously named `.md` file. 4. The shell expands the filename directly into the unquoted Python heredoc. 5. Python parses the injected text as source code and executes it under the scanner account. ### Impact Assessment Exploitation provides arbitrary code execution with the privileges of the account running `scan-obsidian.sh`. The attacker could access user-readable files, alter the task registry, modify repositories, invoke authenticated command-line tools, or establish additional persistence available to that user. The issue is remotely relevant wherever the Obsidian directory is synchronized from an ...[truncated 51 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/check-agents.sh:41
Finding

Arbitrary Python Execution Through Interpolated Task Metadata

Content
View full analysis
/dev/null || \ python3 -c " import pathlib p = pathlib.Path(r'''$_NO_NOTE''') t = p.read_text('utf-8') p.write_text(t.replace('### $_NO_TNAME\nstatus: in_progress', '### $_NO_TNAME\nstatus: ready'), 'utf-8') " 2>/dev/null log " Obsidian reset to ready: $_NO_TNAME" fi ``` ```bash if [ -n "$NOTE_FILE" ] && [ -f "$NOTE_FILE" ] && [ -n "$TASK_NAME" ]; then python3 - << PYEOF import re note_file = r'''$NOTE_FILE''' task_name = r'''$TASK_NAME''' task_desc = r'''$DESC''' text = open(note_file,'r',encoding='utf-8').read() parts = re.split(r'(?m)^###\s+', text) ``` ### Technical Analysis Task names, descriptions, and note paths are persisted from Obsidian-derived input into `tasks.json`. During no-output recovery and merged-task writeback, these values are directly interpolated into Python programs. Both `python3 -c "..."` and the unquoted heredoc construct executable source code from attacker-controlled strings. Triple quotes do not provide safe encoding: a crafted value can terminate a literal and append Python statements. Quotes, backslashes, or newlines can also alter parsing and produce denial-of-service conditions even when full code execution is not achieved. ### Attack Path 1. An attacker creates a task with a crafted heading, description, or note filename. 2. The scanner stores that data in `tasks.json` through `spawn-agent.sh`. 3. The task reaches either: - The no-output recovery path, or - The merged-MR writeback path. 4. `check-ag ...[truncated 557 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/spawn-agent.sh:117
Finding

Automatic npm Lifecycle Script Execution from Unreviewed Repositories

Content
View full analysis
> "$LOG_FILE" 2>&1 echo " ✓ Done" fi ``` ### Technical Analysis The orchestration process automatically runs `npm install` whenever a newly prepared worktree contains `package.json`. By default, npm may execute package lifecycle hooks such as `preinstall`, `install`, and `postinstall`. These hooks can originate from the repository itself or from installed dependencies. The installation occurs before the coding and review stages, without requiring a lockfile, suppressing lifecycle scripts, pinning an approved registry, or isolating execution. Consequently, cloning or updating an untrusted or compromised repository can immediately produce arbitrary local code execution. ### Attack Path 1. An attacker compromises a registered repository or convinces an operator to register an untrusted repository. 2. The attacker adds a malicious lifecycle script to `package.json` or introduces a dependency whose package executes an install hook. 3. A task is spawned for the project. 4. The orchestrator clones or updates the repository and creates a worktree. 5. `npm install` automatically runs the malicious lifecycle code before any review occurs. 6. The payload executes with the orchestrator user’s filesystem, network, and credential access. ### Impact Assessment A malicious installation script receives the privileges of the user running `spawn-agent.sh`. It may read local credentials, alter source code, tamper with the task registry, compromise other repositories, contact external systems, or modify the orchestration scripts. The scope is broader than the target project becaus ...[truncated 91 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:173
Finding

Ambiguous Chat Intent Can Trigger an Irreversible Authenticated Merge Without Confirmation

Content
View full analysis
` and `` from the notification, run `merge-and-sync.sh ` | | "起任务" / "spawn" / "新任务" | With a task description | Run `spawn-agent.sh ""` | | "查状态" / "check status" | Any | Run `check-agents.sh` and summarize output | | "新项目" / "new project" | With a project name | Run `new-project.sh ` | ``` ```bash swarm_mr_merge() { local iid="$1" case "$SWARM_GIT_PROVIDER" in gitlab) glab mr merge "$iid" --yes --remove-source-branch --auto-merge=false ;; github) gh pr merge "$iid" --merge --delete-branch ;; esac } ``` ### Technical Analysis The Skill explicitly directs the dispatcher to execute a merge immediately when a user responds with a short phrase such as “merge,” without requesting confirmation. The merge commands are noninteractive and delete the source branch. Authorization depends on conversational context and identifier extraction from a prior notification. The workflow does not require an explicit repository-qualified confirmation and does not demonstrate validation that the selected merge request belongs to the intended project, has the expected source and target branches, or still satisfies review and CI requirements. This creates a confused-deputy risk: spoofed, stale, or misassociated notification context can cause authenticated Git tooling to merge the wrong change. ### Attack Path 1. An attacker or accidental message introduces a forged, stale, or misleading `PR ...[truncated 1036 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code chunk is narrowly focused on bootstrapping a new project: ensuring a remote repo exists, cloning or initializing a local repo, creating context.md, registering the project in registry.json, and creating an Obsidian note. The declared description instead emphasizes orchestration of agent-swarm coding workflows across existing projects, including task intake, Claude/Codex execution and review, GitLab MR flow, merge+sync, and closing done tasks. Those workflow behaviors are not present in this code, while repo provisioning and registry mutation are substantive capabilities not reflected in the description. This is a material description-behavior mismatch, not just an implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The code is broadly aligned with the declared workflow around code review, automated fixing, pushing, and merge request creation. However, the declared description explicitly includes merge+sync and done-status closure, while this script stops at creating the MR and marking the task as "ready_to_merge". It does not merge branches, sync post-merge, or close the task as done. It also does not implement Obsidian intake in this chunk. These are material gaps between the declared description and the actual behavior of the supplied code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

This code chunk does not implement the declared orchestration capabilities such as Obsidian task intake, Claude/Codex coding workflow, GitLab MR flow, merge/sync, or done-status closure. Instead, it performs a distinct operational task: processing queued notification files and sending them through a notifier function. While notifications could be a supporting component of a larger swarm system, the declared description does not mention this capability, and the actual code's primary purpose is materially different from the stated workflow orchestration behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a broad automation/orchestration skill for agent-swarm project workflows spanning task intake, coding, review, MR handling, merge/sync, and status closure. The actual code chunk only performs a Git synchronization step for a single named project: it reads project metadata from a registry, validates a local repo, fetches from origin, checks out the base branch, and fast-forward pulls. While 'sync' is one small piece mentioned in the description, this code alone does not implement or demonstrate the larger declared workflow capabilities, so the description materially overstates what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
97% confidence
Finding

The skill relies on and documents access to sensitive agent configuration under ~/.claude.json and ~/.claude/settings.json, including trusted-project state and disabled dangerous-mode prompts. Access to agent config directories can expose authentication context and lower safety barriers, increasing the blast radius if the workflow or downstream agent is compromised.

Content

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

md
### Claude Code CLI
- Authenticated via OAuth (`~/.claude.json` oauthAccount)
- `~/.claude/settings.json`: `skipDangerousModePermissionPrompt: true`
- `~/.claude.json` projects: trust `~/GitLab/worktrees` and `~/GitLab/repos` (`hasTrustDialogAccepted: true`)
- No `ANTHROPIC_*` env vars leaking into tmux (causes proxy conflicts)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The coding and review helpers invoke external agent CLIs with explicit permission/sandbox bypass flags such as --dangerously-skip-permissions and --dangerously-bypass-approvals-and-sandbox. In an orchestrator that may pass untrusted task content to agents, this materially increases the chance that prompt-influenced agent actions can modify files, access sensitive data, or perform unintended commands without human approval.

Content

No source excerpt is available for this finding.

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
98% confidence
Finding

This command sends prompts to an external model provider while explicitly disabling normal permission safeguards. In an agent-swarm orchestration setting where prompts may derive from tasks, repositories, or other semi-trusted sources, this can enable unsafe autonomous actions and unintended disclosure of local project content to the provider.

Content

Scanner excerpt · scripts/config.sh (reported line 151)May include surrounding context.

sh
local prompt="$1" log_file="$2"
    case "$SWARM_CODING_AGENT" in
        claude)
            claude --dangerously-skip-permissions -p "$prompt" 2>&1 | tee -a "$log_file"
            ;;
        codex)
            echo "$prompt" | codex exec --dangerously-bypass-approvals-and-sandbox - 2>&1 | tee -a "$log_file"

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
97% confidence
Finding

The review helper reads a prompt file and submits it to Claude with --dangerously-skip-permissions, removing protective friction for whatever instructions the file contains. Since review prompts may include repository data or adversarial content from earlier workflow stages, this increases the risk of unsafe tool use, data exposure, or unauthorized modifications during the review phase.

Content

Scanner excerpt · scripts/config.sh (reported line 172)May include surrounding context.

sh
-c "model_reasoning_effort=high" - 2>&1
            ;;
        claude)
            claude --dangerously-skip-permissions -p "$(cat "$prompt_file")" 2>&1
            ;;
        none)
            echo "REVIEW_RESULT: PASS"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill describes shell execution, file reads, and file writes, but does not declare an explicit tool scope or permission boundary. In a workflow that spawns agents, edits repos, merges MRs, and processes local notes/configs, missing scope makes it easier for an agent or wrapper to overreach and perform unintended system or repository changes.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
93% confidence
Finding

The instruction to take actions immediately without asking for confirmation enables autonomous execution of shell scripts based on natural-language matching. In this skill's context, those actions include spawning agents, project initialization, status checks, and merges, so a mistaken or manipulated interpretation can lead to unauthorized state changes.

Content

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

md
## Intent → Action Mapping

When a user message matches one of these intents, take the corresponding action immediately without asking for confirmation:

| User says | Context | Action |
|-----------|---------|--------|

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to merge merge requests immediately on simple trigger phrases without explicit confirmation or a warning that this changes repository state. In this context, merges can land unreviewed or malicious code, trigger deployments, and permanently alter project history, making the automation materially risky.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The guardrail claims the dispatcher should not read or modify project code directly, yet the documented workflow explicitly invokes scripts that operate on full repositories and cause coding agents to change code. This contradiction can mislead users about the actual trust boundary and may cause them to submit sensitive tasks under the assumption of a safer, narrower role.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
65% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/check-agents.sh (reported line 36)May include surrounding context.

sh
if [ "$HAS_COMMITS" -gt 0 ]; then
        log "Agent done with $HAS_COMMITS commits, triggering review..."
        jq --arg id "$TASK_ID" '.tasks |= map(if .id == $id then .status = "reviewing" else . end)' "$TASKS_FILE" > "${TASKS_FILE}.tmp" && mv "${TASKS_FILE}.tmp" "$TASKS_FILE"
        nohup "$SCRIPTS_DIR/review-and-push.sh" "$TASK_ID" >> "${LOGS_DIR}/${TASK_ID}.log" 2>&1 &
      else
        log "no-output: $TASK_ID"
        jq --arg id "$TASK_ID" '.tasks |= map(if .id == $id then .status = "no-output" else . end)' "$TASKS_FILE" > "${TASKS_FILE}.tmp" && mv "${TASKS_FILE}.tmp" "$TASKS_FILE"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This shell script performs irreversible cleanup actions including forced git worktree removal, recursive directory deletion, and file deletion via find -delete. Although it writes to an internal log file, there is no user-facing disclosure, confirmation, or inline warning comment clearly alerting operators to these destructive behaviors.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The merge helper performs repository-changing operations and explicitly deletes the source branch via --remove-source-branch or --delete-branch. In this file there is no confirmation prompt, warning comment, or user-facing log indicating that merging will also remove branches, so the destructive behavior is undisclosed here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The notification helper transmits arbitrary message content to external targets via OpenClaw or a webhook URL from configuration, which can leak task details, repository names, branch names, or other sensitive workflow metadata. In a multi-project automation context, silent outbound messaging broadens the data exfiltration surface, especially if message content can include agent output or secrets.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

This curl POST sends message content to an externally configured webhook endpoint, creating a direct exfiltration path for any data placed into msg. Because the target is fully configurable and there is no validation, redaction, or user prompt, sensitive workflow information could be transmitted off-host without visibility.

Content

Scanner excerpt · scripts/config.sh (reported line 190)May include surrounding context.

sh
--target "$SWARM_NOTIFY_TARGET" --message "$msg" >/dev/null 2>&1
            ;;
        webhook)
            curl -s -X POST "$SWARM_NOTIFY_TARGET" \
                -H "Content-Type: application/json" \
                -d "{\"text\": $(echo "$msg" | jq -Rs .)}" >/dev/null 2>&1
            ;;

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This shell script proceeds from review into git push and MR creation automatically, which are external, potentially irreversible operations affecting remote repositories. Although there is logging, the file does not provide a user-facing warning or confirmation before these actions, and the stated purpose in the header emphasizes review and push but does not disclose the automatic remote publication behavior in a safety-oriented way.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code rewrites the user's Obsidian note to change task status values and also creates deduplication marker files, but the only disclosure is internal logging to a file. There is no confirmation prompt, user-facing print from the shell script entrypoint, or comment/docstring warning that the skill will modify user files automatically.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script forcibly removes an existing git worktree path and, if that fails, falls back to rm -rf on the target directory without any explicit confirmation or strong validation that the path is safe. In an automation/orchestration skill that creates and reuses filesystem paths from configuration, a misconfigured or unexpected SWARM_WORKTREE_BASE/task path could cause unintended deletion of local data or repository state.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The intent mapping instructs immediate execution of merge, spawn, status, and new-project actions without asking for confirmation. The later guardrail section frames the skill as a dispatcher that should understand intent and translate requests into clear task descriptions, which conflicts with the unconditional immediate-action instruction for terse trigger phrases.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The intent mapping hard-codes supported user utterances in Chinese and English only, which can impose a language constraint without stating whether other languages are supported or offering user choice. Under the language/locale policy, skills should avoid silently forcing a specific language unless the limitation is explicitly justified or opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

Natural-language strings in the file describe the skill exclusively in Chinese, which can indicate a fixed language/locale expectation. There is no indication that this locale restriction is optional, user-selected, or justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This helper invokes glab/gh to create remote repositories, which transmits metadata to an external service and changes remote state. The file contains no user-facing warning, prompt, or explanatory comment near the operation describing that it may create private repositories on GitHub or GitLab.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This shell script includes user-facing natural-language text only in Chinese in its header comments and usage description. The provided policy says to flag language or locale constraints when a skill forces a specific language without user opt-in, and there is no indication here that the skill is region-specific or offers a language choice.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.