Back to skill

Security audit

CLI Butler

Security checks for vulnerabilities and agentic risk

Overview

ClawScan marks this skill suspicious because scanners report serious mismatches with its stated CLI-management purpose and unsafe package-management behavior; analysis was also incomplete.

Consider avoiding installation until the author clarifies the unrelated agent-session functionality and addresses the reported uninstall and package-routing risks. The installer is unpinned, and the scan is partial, so the available results do not establish that all relevant code was fully inspected.

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
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (65)

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied code has a materially different primary purpose from the description: agent-session journaling and handover coordination. It contains no package-manager integration, CLI inventory, installation, upgrade, removal, provenance tracing, or capability enumeration. Its lifecycle triggers and project-documentation writes are unrelated to the declared CLI-management workflow. The logging is scoped to the project and excludes prompt and transcript contents, but these safeguards do not resolve the purpose mismatch.

Content

No source excerpt is available for this finding.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `bin/list.sh` | Inventory every CLI grouped by channel, each with a one-line description; system-bundled CLIs get their own group marked non-uninstallable. `-

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `bin/manage.sh` | `info <cli>` / `outdated` / `upgrade <cli>` |

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `bin/install.sh` | Install via the right channel, record provenance |

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `bin/uninstall.sh` | Channel-routed uninstall; manual items go through refchain + dry-run + confirm |

Manual uninstall deletes app-embedded symlinks despite promising to preserve them as .bak backups.

High
Category
Excessive Agency
Confidence
99% confidence
Finding

The manual/untracked branch unconditionally runs rm on the resolved command path after --yes, without checking whether it is an app-embedded symlink that should instead be backed up. If such a path reaches this branch, the link is permanently removed, potentially breaking application functionality and violating the stated recovery guarantee; rm removes the link itself, not its target.

Content

No source excerpt is available for this finding.

Upgrade and uninstall routing uses the command name instead of the owning package identifier.

High
Category
Excessive Agency
Confidence
99% confidence
Finding

Ownership resolution retains only a channel/category, while route builders use the supplied CLI name directly as the package-manager target. When executable and package names differ, an upgrade or uninstall can fail or target an unrelated same-named package; confirmation does not repair this incorrect target selection.

Content

No source excerpt is available for this finding.

Collaboration and commit languages are mandated without user choice.

Medium
Category
Output Handling
Confidence
96% confidence
Finding

L04 requires Simplified Chinese for collaboration, and L08 requires English commit messages, without offering user opt-in or a language choice. Unlike the English documentation requirement, which is justified by its open-source audience, these mandates have no explicit justification.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · AGENTS.md (reported line 6)May include surrounding context.

md
- 需求真相源:`docs/REQUIREMENTS.md`;渠道模型口径:`docs/provenance.md`。改需求先改文档再动代码。
- 协作语言:简体中文;`SKILL.md` 与 README 面向开源,用英文。
- 技术约束:POSIX bash、零第三方依赖;单渠道探测失败不阻塞整体;危险操作默认 dry-run。
- 安全红线(不可协商):渠道管理的二进制禁止直接 `rm`;launchd 停用须挪 plist;app 内嵌软链只备份挪链。
- 每次改动后跑 `tests/run.sh`;shellcheck 在 CI 跑,本地装了就一并跑。
- 提交信息用英文祈使句;一个功能一个 commit。
- 开源发布前:npm / GitHub / skills.sh 名字查重。

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · HANDOVER.md (reported line 40)May include surrounding context.

md
## 5. 可继续方向(实现顺序 F1→F5→F6→F3→F4→F2)

1. **F1 list**:逐渠道枚举(命令清单见 provenance.md 渠道表)+ PATH 无主二进制 + 合并去重 + 分组输出(组头渠道说明)+ desc 本地采集 + system 组标注;对数本机真实数据(docker=OrbStack 软链、node/nvm、dsh 残留 .off plist、homebrew 包、/usr/bin 系统自带)。
2. **F5 refchain**:五层输出 + zsh 历史 epoch 判活(mtime 不可信);用 /usr/local/bin/docker 软链链与 ai.deepseek.dsh.web.plist.off 验证。
3. **F6 cap**:--help/-h/help 试探 + 顶层子命令提取。
4. **F3 install**:OS/渠道探测 → 路由 → journal 回写;代理检测(webget 在列时用之);npm prefix 核对防劫持。

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · HANDOVER.md (reported line 41)May include surrounding context.

md
## 5. 可继续方向(实现顺序 F1→F5→F6→F3→F4→F2)

1. **F1 list**:逐渠道枚举(命令清单见 provenance.md 渠道表)+ PATH 无主二进制 + 合并去重 + 分组输出(组头渠道说明)+ desc 本地采集 + system 组标注;对数本机真实数据(docker=OrbStack 软链、node/nvm、dsh 残留 .off plist、homebrew 包、/usr/bin 系统自带)。
2. **F5 refchain**:五层输出 + zsh 历史 epoch 判活(mtime 不可信);用 /usr/local/bin/docker 软链链与 ai.deepseek.dsh.web.plist.off 验证。
3. **F6 cap**:--help/-h/help 试探 + 顶层子命令提取。
4. **F3 install**:OS/渠道探测 → 路由 → journal 回写;代理检测(webget 在列时用之);npm prefix 核对防劫持。
5. **F4 uninstall**:渠道路由 + manual 走 refchain→dry-run→确认;清扫残留。

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · HANDOVER.md (reported line 52)May include surrounding context.

md
- 渠道管理的二进制**永不直接 `rm`**。
- 卸载类操作**默认 dry-run**,显式确认才执行。
- launchd 停用须挪 plist(`.plist.off`),不能只 `launchctl bootout`。
- app 内嵌软链只备份挪链(`.bak`),不动 .app 内部。
- 删除、force push、改共享配置等危险操作须先确认(全局 AGENTS.md 规则)。
- 自动记录:钩子尚未接入具体 agent(用户未确认新会话用哪个),任务记录先手写 `tasks/` 目录(本 repo 暂无该目录,首个任务时建)。

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · HANDOVER.md (reported line 52)May include surrounding context.

md
- 渠道管理的二进制**永不直接 `rm`**。
- 卸载类操作**默认 dry-run**,显式确认才执行。
- launchd 停用须挪 plist(`.plist.off`),不能只 `launchctl bootout`。
- app 内嵌软链只备份挪链(`.bak`),不动 .app 内部。
- 删除、force push、改共享配置等危险操作须先确认(全局 AGENTS.md 规则)。
- 自动记录:钩子尚未接入具体 agent(用户未确认新会话用哪个),任务记录先手写 `tasks/` 目录(本 repo 暂无该目录,首个任务时建)。

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · SKILL.md (reported line 35)May include surrounding context.

md
1. **Never `rm` a binary owned by a package manager.** Always route through the owning channel (`brew uninstall`, `npm uninstall -g`, …). Direct deletion corrupts the channel's database.
2. **Uninstall is dry-run first.** Show planned actions, require explicit confirmation (`--yes` or interactive).
3. **launchd services are disabled by moving the plist away** (e.g. to `.plist.off`), never by `launchctl bootout` alone — bootout only unregisters the current session; the service returns on next login.
4. **App-embedded symlinks** (e.g. `/usr/local/bin/docker` → inside an .app): move the symlink aside (`.bak`), never delete the app's internals.
5. Single channel probe failures never block the whole inventory; report them, don't guess.
6. **System-bundled CLIs are never uninstalled.** Anything under macOS SIP-protected prefixes (`/usr/bin`, `/bin`, `/sbin`, `/usr/sbin`) is listed but refused on uninstall, with the reason stated.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · SKILL.md (reported line 35)May include surrounding context.

md
1. **Never `rm` a binary owned by a package manager.** Always route through the owning channel (`brew uninstall`, `npm uninstall -g`, …). Direct deletion corrupts the channel's database.
2. **Uninstall is dry-run first.** Show planned actions, require explicit confirmation (`--yes` or interactive).
3. **launchd services are disabled by moving the plist away** (e.g. to `.plist.off`), never by `launchctl bootout` alone — bootout only unregisters the current session; the service returns on next login.
4. **App-embedded symlinks** (e.g. `/usr/local/bin/docker` → inside an .app): move the symlink aside (`.bak`), never delete the app's internals.
5. Single channel probe failures never block the whole inventory; report them, don't guess.
6. **System-bundled CLIs are never uninstalled.** Anything under macOS SIP-protected prefixes (`/usr/bin`, `/bin`, `/sbin`, `/usr/sbin`) is listed but refused on uninstall, with the reason stated.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/refchain.sh (reported line 68)May include surrounding context.

sh
done
IFS=$IFS0

# layer 4: launchd plists (incl. disabled suffixes) + crontab
IFS0=$IFS; IFS=:
# shellcheck disable=SC2086  # knob is a colon/space list on purpose
for d in ${BUTLER_LAUNCHD_DIRS:-"$HOME/Library/LaunchAgents" /Library/LaunchAgents /Library/LaunchDaemons}; do

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/refchain.sh (reported line 74)May include surrounding context.

sh
for d in ${BUTLER_LAUNCHD_DIRS:-"$HOME/Library/LaunchAgents" /Library/LaunchAgents /Library/LaunchDaemons}; do
  IFS=$IFS0
  [ -d "$d" ] || continue
  for f in "$d"/*.plist "$d"/*.plist.*; do
    [ -f "$f" ] || continue
    if grep -qF -- "$name" "$f" 2>/dev/null || grep -qF -- "$rp" "$f" 2>/dev/null; then
      case "$f" in

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/refchain.sh (reported line 74)May include surrounding context.

sh
for d in ${BUTLER_LAUNCHD_DIRS:-"$HOME/Library/LaunchAgents" /Library/LaunchAgents /Library/LaunchDaemons}; do
  IFS=$IFS0
  [ -d "$d" ] || continue
  for f in "$d"/*.plist "$d"/*.plist.*; do
    [ -f "$f" ] || continue
    if grep -qF -- "$name" "$f" 2>/dev/null || grep -qF -- "$rp" "$f" 2>/dev/null; then
      case "$f" in

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/refchain.sh (reported line 78)May include surrounding context.

sh
[ -f "$f" ] || continue
    if grep -qF -- "$name" "$f" 2>/dev/null || grep -qF -- "$rp" "$f" 2>/dev/null; then
      case "$f" in
        *.plist) echo "launchd-ref=$f" ;;
        *) echo "launchd-ref=$f (disabled)" ;;
      esac
    fi

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/uninstall.sh (reported line 4)May include surrounding context.

sh
#!/usr/bin/env bash
# shellcheck disable=SC1091  # sibling lib files are sourced at runtime
# cli-butler F4: uninstall — system refusal, channel routing, dry-run-by-default
# for manual/untracked, launchd plist moved (not bootout-only), journal writeback.
# Red lines (REQUIREMENTS.md): system items are never uninstalled; channel-owned
# paths are removed via their channel, never `rm`'d; app-internal symlinks are
# only moved to .bak, never deleted.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/uninstall.sh (reported line 24)May include surrounding context.

sh
system item          refused outright (SIP / system integrity) — no plan, no action
  channel item         plan via owning channel; --yes runs the channel's uninstall
  manual (journaled)   refchain summary + dry-run; --yes removes file, clears journal,
                       moves referencing launchd plists to *.plist.off
  untracked            same gate as manual (refchain shown first)
EOF
}

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/uninstall.sh (reported line 24)May include surrounding context.

sh
system item          refused outright (SIP / system integrity) — no plan, no action
  channel item         plan via owning channel; --yes runs the channel's uninstall
  manual (journaled)   refchain summary + dry-run; --yes removes file, clears journal,
                       moves referencing launchd plists to *.plist.off
  untracked            same gate as manual (refchain shown first)
EOF
}

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/uninstall.sh (reported line 75)May include surrounding context.

sh
echo "refs: checking references for '$name' ($path) before removal"
"$BIN_DIR/refchain.sh" "$name" 2>/dev/null | sed 's/^/refs:   /'
echo "plan: rm $path"
# launchd plists referencing this binary are moved aside (dsh lesson: bootout
# alone only ends the current session; the plist must be moved to stay disabled)
PLIST_HIT=$(find "$HOME/Library/LaunchAgents" /Library/LaunchAgents -maxdepth 1 \
  -name '*.plist' -type f 2>/dev/null | while IFS= read -r pl; do

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · bin/uninstall.sh (reported line 76)May include surrounding context.

sh
"$BIN_DIR/refchain.sh" "$name" 2>/dev/null | sed 's/^/refs:   /'
echo "plan: rm $path"
# launchd plists referencing this binary are moved aside (dsh lesson: bootout
# alone only ends the current session; the plist must be moved to stay disabled)
PLIST_HIT=$(find "$HOME/Library/LaunchAgents" /Library/LaunchAgents -maxdepth 1 \
  -name '*.plist' -type f 2>/dev/null | while IFS= read -r pl; do
    grep -lF -- "$path" "$pl" 2>/dev/null || grep -lF -- "$name" "$pl" 2>/dev/null

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% 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 · docs/REQUIREMENTS.md (reported line 61)May include surrounding context.

md
红线:
- **system(系统自带)项一律拒绝卸载**:直接说明不可卸载及原因(SIP/系统完整性),不进 dry-run 流程。
- **绝不对渠道管理的二进制直接 `rm`**——必须经归属渠道卸载。
- launchd 服务停用:须挪走 plist(而非只 `launchctl bootout`,bootout 只注销当前会话——dsh 教训)。
- app 内嵌软链(OrbStack 型,如 /usr/local/bin/docker → app 内 docker-tools):只备份挪链(`.bak`),不删本体。

### F2 manage — 单项管理与升级