Back to skill

Security audit

qclaw-watchdog

Security checks for vulnerabilities and agentic risk

Overview

This watchdog mostly matches its stated purpose, but it ships real-looking Feishu credentials and allows remote chat messages to control a local app without an in-code sender check.

Review before installing. Replace and rotate the bundled Feishu credentials, remove config.json from distribution, restrict the bot to known senders, add confirmation for restart and quit, avoid broad pkill matching, and decide explicitly whether persistent startup and routine status reporting are acceptable.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
config.json:2
Finding

Hardcoded Feishu Application Credentials and Recipient Identifier

Content
View full analysis
"$CONFIG_FILE" << 'EOF' { "feishu": { "app_id": "YOUR_APP_ID", "app_secret": "YOUR_APP_SECRET", "user_id": "YOUR_USER_OPEN_ID" }, "qclaw": { "health_url": "http://127.0.0.1:28789/health" }, "watchdog": { "check_interval_ms": 180000, "restart_delay_ms": 10000, "max_retries": 3 }, "logs": { "main_log": "./watchdog.log", "command_log": "./commands.log" } } EOF ``` The resulting permissions depend on the user's current `umask`, which may allow other local users to read the secret. ### Attack Path 1. An attacker obtains the Skill archive, repository contents, backup, or another copy of `config.json`. 2. The attacker extract ...[truncated 860 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
watchdog.js:467
Finding

Remote Process-Control Commands Lack Sender Authorization

Content
View full analysis
{ log(`收到消息事件`); try { const message = data.message || {}; log(`消息类型: ${message.message_type}`); log(`消息内容: ${message.content}`); if (message.message_type === 'text') { const content = JSON.parse(message.content); const text = content.text?.trim() || ''; const messageId = message.message_id; log(`收到指令: "${text}"`); await this.handleCommand(text, messageId); } } catch (e) { log(`处理消息失败: ${e.message}`); } } }); ``` The handler passes every received text message to the command dispatcher without checking the sender, chat, tenant, or configured `USER_ID`. Administrative commands ultimately reach process-control methods such as: ```javascript async restartQclaw() { try { await execPromise('osascript -e \'tell application "QClaw" to quit\''); await new Promise(r => setTimeout(r, 3000)); await execPromise('pkill -f QClaw').catch(() => {}); await new Promise(r => setTimeout(r, 2000)); await execPromise('open -a QClaw'); return '已重启 QClaw'; } catch (e) { return `重启失败: ${e.message}`; } } async quitQclaw() { try { await execPromise('osascript -e \'tell application "QClaw" to quit\''); return '已退出 QClaw'; } catch (e) { return `退出失败: ${e.message}`; } } ``` ### Technical Analysis The configured `USER_ID` is used only as the destination for proactive messages. It is not used to authorize incoming events. No comparison is made against sender identity fields in the event payload, and there is no allowlist for permitted chats or tenants. Consequently, any Feishu user who can cause an `im.message.receive_v1` ev ...[truncated 1503 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
watchdog.js:122
Finding

Internal Host Status Is Transmitted to a Preconfigured External Recipient

Content
View full analysis
p); log(` 判断: QClaw 进程存在 (PID: ${pids.join(', ')}),但 Gateway 无响应`); return { status: 'no_response', detail: `QClaw 进程在运行 (PID: ${pids.join(', ')}) 但 Gateway 无响应` }; ``` These details are embedded in outbound cards during monitoring, including: ```javascript const card = this.buildCard( '🔴 QClaw 异常检测', `**状态**: ${status}\n**详情**: ${detail}\n**时间**: ${new Date().toLocaleTimeString()}\n\n🔄 正在自动修复...`, 'red' ); await this.sendMessage(card, 'red'); ``` ### Technical Analysis Outbound Feishu notifications are part of the declared watchdog functionality. However, the implementation forwards unfiltered health response objects, process IDs, status data, error details, and timing information to `USER_ID`. The distributed `config.json` contains a fixed recipient ...[truncated 1681 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
watchdog.js:218
Finding

Overbroad Process Termination Using Pattern-Based pkill

Content
View full analysis
setTimeout(r, 3000)); await execPromise('pkill -f QClaw').catch(() => {}); await new Promise(r => setTimeout(r, 2000)); await execPromise('open -a QClaw'); return '已重启 QClaw'; } catch (e) { return `重启失败: ${e.message}`; } } ``` Process detection uses the same broad matching principle: ```javascript const { stdout } = await execPromise('pgrep -f QClaw'); const pids = stdout.trim().split('\n').filter(p => p); ``` ### Technical Analysis `pkill -f QClaw` matches the pattern against each process's full command line. It is not limited to the exact QClaw application executable or to a PID previously verified as belonging to the expected application bundle. Any process owned by the watchdog user whose command line contains `QClaw` may be terminated. This can include helper scripts, terminal commands, development tools, unrelated applications with matching arguments, or monitoring processes. Because the watchdog accepts remote restart commands without sender authorization, this broad termination behavior amplifies the remote-command vulnerability. ### Attack Path 1. A local process is started with `QClaw` anywhere in its command line, whether coincidentally or intentionally. 2. An automatic health failure or remote `restart` command invokes `restartQclaw`. 3. The graceful AppleScript quit is followed by `pkill -f QClaw`. 4. Every user-owned process matching the broad command-line pattern may be terminated. 5. Affected processes can lose transient state or interrupt unrelated work. An attacker capable of sending unauthorized Feishu commands can repeatedly trigger this behavior remotely. ### Impact Assessment Th ...[truncated 407 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 (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description frames the skill as a watchdog, but the document also describes remote command handling, quitting/restarting QClaw, persistent logging, update/publish flows, and OS-level persistence. This behavior expansion matters because remote control of a local process and host state changes are materially more sensitive than passive monitoring.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documents network access, environment-variable secret use, remote messaging, and host interaction, but declares no explicit tool scope or permissions boundary. That omission makes the skill harder to evaluate safely and increases the chance an operator grants broader access than intended.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill advertises auto-restart and remote-control commands without an explicit warning that these actions can change local system state and affect service availability. Users may enable it without understanding that chat messages can trigger operational actions on the host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation instructs users to store Feishu app credentials and user identifiers in a config file or environment variables, but does not warn about protecting those secrets. Exposure of these values could let an attacker impersonate the bot, access messaging functions, or manipulate the watchdog via its communication channel.

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 · SKILL.md (reported line 96)May include surrounding context.

./start.sh

后台运行

nohup ./start.sh >> watchdog.log 2>&1 &

text

### 3. 开机自启 (macOS)

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 102)May include surrounding context.

3. 开机自启 (macOS)

bash
# 编辑 plist,修改路径
vim com.user.qclaw-watchdog.plist

# 复制到 LaunchAgents

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 103)May include surrounding context.

3. 开机自启 (macOS)

bash
# 编辑 plist,修改路径
vim com.user.qclaw-watchdog.plist

# 复制到 LaunchAgents

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 106)May include surrounding context.

3. 开机自启 (macOS)

bash
# 编辑 plist,修改路径
vim com.user.qclaw-watchdog.plist

# 复制到 LaunchAgents

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 107)May include surrounding context.

3. 开机自启 (macOS)

bash
# 编辑 plist,修改路径
vim com.user.qclaw-watchdog.plist

# 复制到 LaunchAgents

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 107)May include surrounding context.

复制到 LaunchAgents

cp com.user.qclaw-watchdog.plist ~/Library/LaunchAgents/ launchctl load ~/Library/LaunchAgents/com.user.qclaw-watchdog.plist

text

## 更新 Update

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script performs restart and quit actions automatically or from simple chat commands without any confirmation step, safeguard, or explicit user approval for destructive operations. In a remote-control context, this increases the chance of accidental outages or malicious triggering via compromised messaging access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The watchdog exposes a remote 'quit' command that shuts down QClaw, which is inconsistent with a monitoring and recovery tool. If the Feishu bot or authorized sender is abused, an attacker can intentionally stop the protected application, causing denial of service through the very control channel meant to preserve availability.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The event handler logs raw message content and command text to local files, which may capture sensitive operational instructions or other private chat content without minimization. If logs are readable by other local users, included in backups, or exfiltrated, this creates a secondary data-leak channel.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code sends periodic 'all clear' status messages during every successful monitoring cycle, which exceeds the stated scope of alerting and command handling in the skill description. This creates unnecessary telemetry and disclosure of operational state to a remote service, increasing privacy and data-exposure risk even if the content is not highly sensitive.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access, suspicious.install_untrusted_source

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
watchdog.js:9

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
config.json:8