Back to skill

Security audit

Kindle Claude Monitor

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Claude status monitor, but it installs persistent hooks and exposes unauthenticated Claude activity data and state controls on the local network.

Review this before installing on any machine used for private or client work. Only use it on a trusted LAN, avoid router port forwarding, consider adding authentication or binding the event receiver to localhost, and delete ~/.claude/kindle-monitor/events.jsonl if you uninstall and do not want hook history retained.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/server.py:450
Finding

Unauthenticated LAN Exposure and Modification of Claude Monitor State

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/server.py:240
Finding

Excessive Plaintext Collection and Indefinite Retention of Complete Claude Hook Payloads

Content
View full analysis
/dev/null) if [ -n "$PAYLOAD" ]; then curl -s -m 1 -X POST -H "Content-Type: application/json" \ --data "$PAYLOAD" "http://localhost:$PORT/event" > /dev/null 2>&1 || true fi ) & ``` The server appends the complete payload to a persistent plaintext file: ```python def log_event(event_type, payload): try: os.makedirs(os.path.dirname(LOG_FILE), exist_ok=True) with open(LOG_FILE, "a", encoding="utf-8") as f: f.write(json.dumps({ "t": datetime.now().isoformat(timespec="seconds"), "type": event_type, "payload": payload, }, ensure_ascii=False) + "\n") except Exception: pass ``` The uninstaller removes executable runtime files but retains the event history: ```bash rm -f "$RUNTIME_DIR/server.py" "$RUNTIME_DIR/notify.sh" ``` ### Technical Analysis The Skill registers hooks for seven Claude lifecycle and tool events and forwards each event's entire stdin JSON object. The server then stores that object verbatim in `~/.claude/kindle-monitor/events.jsonl`. The dashboard itself only needs a limited subset of fields, such as: - Event type - Timestamp - Session identifier - Project name - Tool name - A short, sanitized status summary Persisting the complete payload is therefor ...[truncated 2716 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (57)

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The README states that installation appends seven hooks to ~/.claude/settings.json, which modifies the agent's config to ensure ongoing interception of Claude events. In this skill's context that behavior is core functionality rather than obviously malicious, but it is still security-relevant because it changes trusted agent behavior and creates a persistent data-forwarding path from future sessions.

Content

Scanner excerpt · README.md (reported line 37)May include surrounding context.

md
1. 拷 `server.py` / `notify.sh` 到 `~/.claude/kindle-monitor/`
2. 渲染并装 launchd plist 到 `~/Library/LaunchAgents/com.user.kindle-monitor.plist`
3. 启动 server(绑定 0.0.0.0:8787)
4. 在 `~/.claude/settings.json` 的 `hooks` 里 append 7 个 kindle 钩子(不动既有 hooks)
5. 检测 macOS 防火墙隐身模式,提示用户手动关
6. 报告 Mac 局域网 IP,告诉你 Kindle 上输入哪个 URL

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · README.md (reported line 121)May include surrounding context.

md
| 现象 | 修法 |
|---|---|
| Kindle 转圈连不上 | macOS stealth mode 把 LAN 包丢了 → `sudo socketfilterfw --setstealthmode off` |
| 浏览器都连不上 | server 没起 → `launchctl list \| grep kindle-monitor`;看 `~/.claude/kindle-monitor/launchd.err.log` |
| Mac 端能开 localhost 但 Kindle 连不上 | Mac IP 变了 → `ipconfig getifaddr en0` 拿新 IP;路由器后台给 Mac 设静态 DHCP 一劳永逸 |
| 一直卡在「请确认」但实际没在等 | 浏览器开 `/reset`,或等 5 分钟超时 |
| 短命令偶发误判为 waiting | 调大 `KINDLE_MONITOR_TOOL_STALL`(默认 20s) |

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
94% confidence
Finding

Editing ~/.claude/settings.json to append seven hooks changes core agent behavior and affects future sessions, which is sensitive because hook configuration can execute logic on multiple lifecycle events. In the context of an agent skill, modifying the main config directory is particularly dangerous because a mistake, abuse, or later compromise of the installed scripts could impact all subsequent agent runs.

Content

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

md
`install.sh` 会做这些事:
- 把 `server.py` / `notify.sh` 拷到 `~/.claude/kindle-monitor/`
- 把 launchd plist 写到 `~/Library/LaunchAgents/` 并启动
- 在 `~/.claude/settings.json` 的 hooks 里 append 7 个 kindle 钩子(不动既有 hooks)
- 处理 macOS 防火墙隐身模式(如有需要会提示用户用 sudo 关闭)
- 报告 Mac 局域网 IP,告诉你 Kindle 上输入什么 URL

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

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

md
| 现象 | 原因 | 修法 |
|---|---|---|
| Kindle 转圈连不上 | macOS stealth mode 把 LAN 包丢了 | `sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off` |
| 浏览器都连不上 | server 没起来 | `launchctl list \| grep kindle-monitor` 看是否 running,看 `~/.claude/kindle-monitor/launchd.err.log` |
| Mac 端能开 localhost 但 Kindle 连不上 | Mac IP 变了 | `ipconfig getifaddr en0` 拿新 IP,路由器后台给 Mac 设静态 DHCP 租约一劳永逸 |
| 显示一直停在「请确认」但没在等 | 虚拟 session 锁死 | 浏览器开 `http://<Mac-IP>:8787/reset`,或等 5 分钟 |
| 事件流里看到 `~PreToolUse` | 来自其他 session 的事件被锁住时只追加不抢 banner | 这是设计行为,不是 bug |

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

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

md
| 现象 | 原因 | 修法 |
|---|---|---|
| Kindle 转圈连不上 | macOS stealth mode 把 LAN 包丢了 | `sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off` |
| 浏览器都连不上 | server 没起来 | `launchctl list \| grep kindle-monitor` 看是否 running,看 `~/.claude/kindle-monitor/launchd.err.log` |
| Mac 端能开 localhost 但 Kindle 连不上 | Mac IP 变了 | `ipconfig getifaddr en0` 拿新 IP,路由器后台给 Mac 设静态 DHCP 租约一劳永逸 |
| 显示一直停在「请确认」但没在等 | 虚拟 session 锁死 | 浏览器开 `http://<Mac-IP>:8787/reset`,或等 5 分钟 |
| 事件流里看到 `~PreToolUse` | 来自其他 session 的事件被锁住时只追加不抢 banner | 这是设计行为,不是 bug |

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

The script explicitly targets ~/.claude/settings.json and comments that it will append hooks there, indicating direct modification of the agent's configuration directory. Access to agent config is high sensitivity because it enables persistent behavioral changes, automatic command execution on future events, and potential collection of user/session data through hook chaining.

Content

Scanner excerpt · install.sh (reported line 4)May include surrounding context.

sh
#!/bin/bash
# Kindle Claude Monitor — install script
# 把 server.py / notify.sh 部署到 ~/.claude/kindle-monitor/,注册 launchd,
# 在 ~/.claude/settings.json append 7 个 hook(不动既有 hooks)。

set -e

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
95% confidence
Finding

Defining SETTINGS as $HOME/.claude/settings.json confirms intentional access to the agent configuration store. In this skill context, that is more dangerous because the monitor is not just displaying data; it is wiring itself into Claude's future event pipeline via persistent hooks, expanding from visualization into control-plane modification.

Content

Scanner excerpt · install.sh (reported line 12)May include surrounding context.

sh
RUNTIME_DIR="$HOME/.claude/kindle-monitor"
LAUNCH_AGENTS="$HOME/Library/LaunchAgents"
PLIST_DST="$LAUNCH_AGENTS/com.user.kindle-monitor.plist"
SETTINGS="$HOME/.claude/settings.json"

# ---- 1. 检查依赖 ----
echo "==> 检查 python3..."

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Content

Scanner excerpt · uninstall.sh (reported line 10)May include surrounding context.

sh
RUNTIME_DIR="$HOME/.claude/kindle-monitor"
PLIST_DST="$HOME/Library/LaunchAgents/com.user.kindle-monitor.plist"
SETTINGS="$HOME/.claude/settings.json"

echo "==> 停止 launchd 服务"
launchctl unload "$PLIST_DST" 2>/dev/null || true

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 · uninstall.sh (reported line 48)May include surrounding context.

sh
fi

echo "==> 删除运行时文件"
rm -f "$RUNTIME_DIR/server.py" "$RUNTIME_DIR/notify.sh"
echo "    保留: $RUNTIME_DIR/events.jsonl (历史日志)"

cat <<EOF

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README explicitly says Claude hook events are forwarded to a local HTTP server that is intended to be reachable from other devices on the LAN. Even if the payload is only 'status', hook events can contain sensitive project names, tool usage context, and workflow timing metadata, and the documentation does not warn users about data exposure, access control, or network trust assumptions.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
87% confidence
Finding

Installing a launchd plist creates persistence so the monitor server starts automatically, which extends the lifetime of the network-exposed service and any associated logging or event collection. Persistence is expected for a monitor, but it increases risk if the service is misconfigured, exposed to the LAN, or later forgotten by the user.

Content

Scanner excerpt · README.md (reported line 35)May include surrounding context.

md
`install.sh` 做这几件事:

1. 拷 `server.py` / `notify.sh` 到 `~/.claude/kindle-monitor/`
2. 渲染并装 launchd plist 到 `~/Library/LaunchAgents/com.user.kindle-monitor.plist`
3. 启动 server(绑定 0.0.0.0:8787)
4. 在 `~/.claude/settings.json` 的 `hooks` 里 append 7 个 kindle 钩子(不动既有 hooks)
5. 检测 macOS 防火墙隐身模式,提示用户手动关

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README instructs users to disable macOS stealth mode to make the service reachable, but does not clearly warn that this increases the host's network visibility and potentially broadens exposure of the monitor service. In the context of a server bound to 0.0.0.0, this materially lowers a network protection barrier and may make reconnaissance and access by other LAN actors easier.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
90% confidence
Finding

The README includes a sudo command that changes a system firewall setting. Although the command itself is not arbitrary code execution, encouraging elevated execution to weaken a security control is risky because users may run it without understanding the broader exposure it creates.

Content

Scanner excerpt · README.md (reported line 50)May include surrounding context.

如果 Kindle 显示"无法连接",多半是 macOS 防火墙隐身模式:

bash
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off

工作原理

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
89% confidence
Finding

The troubleshooting table repeats sudo-based instructions to disable firewall stealth mode, reinforcing a privileged action that reduces host hardening. Repetition in troubleshooting increases the chance that users treat the change as routine and permanent rather than as a risky exception.

Content

Scanner excerpt · README.md (reported line 120)May include surrounding context.

md
| 现象 | 修法 |
|---|---|
| Kindle 转圈连不上 | macOS stealth mode 把 LAN 包丢了 → `sudo socketfilterfw --setstealthmode off` |
| 浏览器都连不上 | server 没起 → `launchctl list \| grep kindle-monitor`;看 `~/.claude/kindle-monitor/launchd.err.log` |
| Mac 端能开 localhost 但 Kindle 连不上 | Mac IP 变了 → `ipconfig getifaddr en0` 拿新 IP;路由器后台给 Mac 设静态 DHCP 一劳永逸 |
| 一直卡在「请确认」但实际没在等 | 浏览器开 `/reset`,或等 5 分钟超时 |

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill describes shell execution, file writes, environment-variable use, and persistent service setup, but does not declare an explicit tool scope such as permissions or allowed-tools. That mismatch increases the chance the skill will run with broader capabilities than a user expects, especially because it modifies hooks and agent configuration. The issue is primarily inadequate least-privilege declaration rather than overtly malicious behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

Using the broad trigger term "monitor" can cause unintended invocation during unrelated conversations about monitoring, dashboards, or status displays. Accidental activation is risky here because the skill is documented to install files, alter hooks, and start a local service, so an overly broad trigger materially raises the chance of unplanned system changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill documents modifying user files, appending hooks to ~/.claude/settings.json, writing a LaunchAgent plist, and potentially changing firewall settings, but does not present an explicit security warning or consent boundary before those actions. Users may trigger the skill expecting a display setup and not realize it introduces persistence, network listening behavior, and configuration changes.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

Installing a launchd plist with KeepAlive creates persistence across logins and automatic restarts, which is a classic persistence mechanism. While legitimate for a monitor service, persistence is security-relevant because it keeps code running in the background and can preserve compromise or unwanted behavior after the initial session ends.

Content

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

md
`install.sh` 会做这些事:
- 把 `server.py` / `notify.sh` 拷到 `~/.claude/kindle-monitor/`
- 把 launchd plist 写到 `~/Library/LaunchAgents/` 并启动
- 在 `~/.claude/settings.json` 的 hooks 里 append 7 个 kindle 钩子(不动既有 hooks)
- 处理 macOS 防火墙隐身模式(如有需要会提示用户用 sudo 关闭)
- 报告 Mac 局域网 IP,告诉你 Kindle 上输入什么 URL

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
82% confidence
Finding

The skill may prompt the user to use sudo to disable macOS stealth mode, which weakens host network hardening and broadens reachability from the LAN. Even though the text says "if needed," introducing privileged changes for convenience increases attack surface and may normalize risky administrative actions.

Content

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

md
- 把 `server.py` / `notify.sh` 拷到 `~/.claude/kindle-monitor/`
- 把 launchd plist 写到 `~/Library/LaunchAgents/` 并启动
- 在 `~/.claude/settings.json` 的 hooks 里 append 7 个 kindle 钩子(不动既有 hooks)
- 处理 macOS 防火墙隐身模式(如有需要会提示用户用 sudo 关闭)
- 报告 Mac 局域网 IP,告诉你 Kindle 上输入什么 URL

## Kindle 端配置

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Mentioning launchctl load/unload further indicates long-lived session persistence. The risk is limited compared with stealthy persistence because it is openly documented, but it still affects the host beyond one-time skill execution.

Content

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

md
| `KINDLE_MONITOR_REFRESH` | 3 | meta refresh 秒数 |
| `KINDLE_MONITOR_WAITING_TIMEOUT` | 300 | waiting 锁超时秒数 |

改了之后改 plist 里的 EnvironmentVariables 块,然后 `launchctl unload && launchctl load` 一次。

## 卸载

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Mentioning launchctl load/unload further indicates long-lived session persistence. The risk is limited compared with stealthy persistence because it is openly documented, but it still affects the host beyond one-time skill execution.

Content

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

md
| `KINDLE_MONITOR_REFRESH` | 3 | meta refresh 秒数 |
| `KINDLE_MONITOR_WAITING_TIMEOUT` | 300 | waiting 锁超时秒数 |

改了之后改 plist 里的 EnvironmentVariables 块,然后 `launchctl unload && launchctl load` 一次。

## 卸载

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

The uninstall section confirms a LaunchAgents plist is created and later removed, validating persistent installation behavior. Transparent uninstall helps, but the persistence itself remains security-relevant because it introduces an always-on local service.

Content

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

bash ~/.claude/skills/kindle-claude-monitor/uninstall.sh

text

会停 launchd、删 LaunchAgents plist、从 settings.json 移除 7 个 kindle 钩子(保留其他不动)。

## 故障排查

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

The troubleshooting advice explicitly suggests a sudo command to disable stealth mode system-wide. In context, this is more dangerous because the skill already exposes a local HTTP service to the network, so reducing firewall stealth further increases discoverability and exposure of that service.

Content

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

md
| 现象 | 原因 | 修法 |
|---|---|---|
| Kindle 转圈连不上 | macOS stealth mode 把 LAN 包丢了 | `sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode off` |
| 浏览器都连不上 | server 没起来 | `launchctl list \| grep kindle-monitor` 看是否 running,看 `~/.claude/kindle-monitor/launchd.err.log` |
| Mac 端能开 localhost 但 Kindle 连不上 | Mac IP 变了 | `ipconfig getifaddr en0` 拿新 IP,路由器后台给 Mac 设静态 DHCP 租约一劳永逸 |
| 显示一直停在「请确认」但没在等 | 虚拟 session 锁死 | 浏览器开 `http://<Mac-IP>:8787/reset`,或等 5 分钟 |

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

This duplicate plist-related indicator points to the same persistence mechanism: storage of a LaunchAgent plist in the user's LaunchAgents directory. In context, persistence is somewhat expected for a monitor, but still dangerous because it increases runtime exposure and survives beyond the installing shell session.

Content

Scanner excerpt · install.sh (reported line 11)May include surrounding context.

sh
SKILL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
RUNTIME_DIR="$HOME/.claude/kindle-monitor"
LAUNCH_AGENTS="$HOME/Library/LaunchAgents"
PLIST_DST="$LAUNCH_AGENTS/com.user.kindle-monitor.plist"
SETTINGS="$HOME/.claude/settings.json"

# ---- 1. 检查依赖 ----

Session Persistence

Medium
Category
Rogue Agent
Confidence
86% confidence
Finding

This duplicate plist-related indicator points to the same persistence mechanism: storage of a LaunchAgent plist in the user's LaunchAgents directory. In context, persistence is somewhat expected for a monitor, but still dangerous because it increases runtime exposure and survives beyond the installing shell session.

Content

Scanner excerpt · install.sh (reported line 11)May include surrounding context.

sh
SKILL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
RUNTIME_DIR="$HOME/.claude/kindle-monitor"
LAUNCH_AGENTS="$HOME/Library/LaunchAgents"
PLIST_DST="$LAUNCH_AGENTS/com.user.kindle-monitor.plist"
SETTINGS="$HOME/.claude/settings.json"

# ---- 1. 检查依赖 ----