Back to skill

Security audit

Mcp Health Monitor

Security checks for vulnerabilities and agentic risk

Overview

This monitoring skill is mostly transparent about checking and restarting services, but it uses a risky configuration-loading pattern that can execute arbitrary shell code repeatedly when scheduled.

Review before installing. Use a dedicated, locked-down config file instead of ~/.env, do not enable LaunchAgent or cron until the config-loading issue is fixed, and confirm every service label because the script can automatically stop and start live services. Telegram alerts are optional but will send service failure details to Telegram.

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/healthcheck.sh:9
Finding
Arbitrary Shell Command Execution Through Sourced Environment File<![CDATA[ ## Vulnerability Details **File Location**: `scripts/healthcheck.sh`, lines 9-33 **Vulnerability Type**: Unsafe execution of a configuration file **Risk Level**: High ### Vulnerable Code ```bash ENV_FILE="${ENV_FILE:-$HOME/.env}" # --- Load environment variables --- if [[ -f "$ENV_FILE" ]]; then # shellcheck disable=SC1090 source "$ENV_FILE" fi ``` ### Technical Analysis The script loads its environment configuration using the Bash `source` command. `source` does not treat the selected file as a data-only collection of key-value pairs; it executes the entire file as shell code in the current process. The default value is the generic path `$HOME/.env`, which may be shared by unrelated applications. The caller can also select another path through `ENV_FILE`. Consequently, any shell construct in the selected file—including command substitutions, function calls, redirections, or arbitrary commands—will execute with the privileges of the user running the monitor. This exceeds the access needed to read the two documented Telegram settings. The monitor only needs `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID`, but instead grants the configuration file unrestricted code-execution capability. The documented LaunchAgent or cron configuration increases the risk because the file may be executed repeatedly and without interactive confirmation. ### Attack Path 1. An attacker obtains write access to `$HOME/.env`, or to another file selected through `ENV_FILE`. 2. The attacker inserts a shell command into that file, for example: ```bash TELEGRAM_CHAT_ID=1234 malicious_command ``` 3. The user manually runs the health monitor, or its configured LaunchAgent/cron schedule invokes it. 4. `source "$ENV_FILE"` executes `malicious_command` as part of the monitoring process. 5. The command inherits the monitor's user identity, environment, filesystem access, and available credentials. 6. If scheduling is enabled, the injected command can run repeatedly ...[truncated 918 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not execute the configuration file with `source`. 2. Use a dedicated configuration path such as `$HOME/.config/mcp-health-monitor/env` rather than the generic `$HOME/.env`. 3. Parse only an explicit allowlist of supported keys, specifically `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID`. 4. Reject shell syntax, command substitutions, unknown variables, malformed lines, and duplicate keys. 5. Verify that the configuration is a regular file owned by the current user and is not a symbolic link. 6. Require restrictive permissions, preferably mode `0600`, and ensure its parent directory is not writable by untrusted users. 7. When scheduling the script, provide a minimal environment and run it as an unprivileged dedicated account where practical. 8. Document that the configuration file contains secrets and must not be shared with unrelated applications. A safer implementation should use a data-only format and a parser that never evaluates file contents as shell commands. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/healthcheck.sh:54
Finding
Telegram Bot Token Exposed in Process Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/healthcheck.sh`, lines 54-60 **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash http_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST \ "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \ -d chat_id="$CHAT_ID" \ -d text="$message" \ -d parse_mode="Markdown" 2>/dev/null || echo "000") ``` ### Technical Analysis Telegram's Bot API places the bot token in the URL path. The script expands that URL directly in the `curl` command line. While `curl` is running, the resulting argument may be observable through process inspection, debugging, audit, monitoring, crash-diagnostic, or job-management tools available on the host. The script does not intentionally send the token anywhere other than Telegram, and the use of HTTPS protects it in transit. The issue is local exposure caused by placing the expanded secret in a process argument. The relevant exposure window is short, but the monitor may run repeatedly and invokes this request whenever failures occur, creating recurring opportunities for observation. ### Attack Path 1. The health monitor is configured with a valid `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID`. 2. A monitored service fails, causing `send_telegram` to invoke `curl`. 3. A local attacker or monitoring component with sufficient process-inspection access observes the `curl` command line during execution. 4. The observer extracts the token from the URL path: ```text https://api.telegram.org/bot<TOKEN>/sendMessage ``` 5. The attacker uses the recovered token to call Telegram Bot API methods as the compromised bot. Exploitation requires local process visibility or access to tooling that records command-line arguments. Whether other unprivileged users can inspect those arguments depends on the operating system and host configuration. ### Impact Assessment A recovered token allows imp ...[truncated 616 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid placing the expanded token directly in ordinary process arguments where the platform and HTTP client permit a less observable transfer mechanism. 2. Store the token in a dedicated, user-owned file with mode `0600`; do not place it in a shared `$HOME/.env`. 3. Restrict process inspection on the monitoring host and run the monitor under a dedicated unprivileged account. 4. Ensure debug tracing such as `set -x` is never enabled around the request. 5. Prevent command-line collection tools, job wrappers, and diagnostic logs from recording the request URL. 6. Minimize the lifetime of secret-bearing HTTP client processes. 7. Rotate the Telegram token immediately if command-line histories, process telemetry, or diagnostic records may already contain it. 8. Restrict the bot's chat membership and operational permissions to the minimum necessary for alert delivery. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Credential Access

High
Category
Privilege Escalation
Content
chmod +x ~/.local/bin/mcp-healthcheck.sh

# Configure (optional — for Telegram alerts)
echo 'TELEGRAM_BOT_TOKEN=your-token' >> ~/.env
echo 'TELEGRAM_CHAT_ID=your-chat-id' >> ~/.env
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
chmod +x ~/.local/bin/mcp-healthcheck.sh

# Configure (optional — for Telegram alerts)
echo 'TELEGRAM_BOT_TOKEN=your-token' >> ~/.env
echo 'TELEGRAM_CHAT_ID=your-chat-id' >> ~/.env
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The markdown states that failed services will be restarted via `launchctl`, which is a system-affecting operation that can change running service state. The README presents this as a feature but does not include a clear user warning about the operational impact or that the skill may stop/start services automatically.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill sends failure notifications through Telegram and instructs users to configure Telegram credentials, but the README does not warn that service health information will be transmitted to an external service. For markdown files, omission of warnings about behaviors affecting privacy or system data handling is in scope.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### Scheduled (macOS LaunchAgent)

See `SKILL.md` for a complete LaunchAgent plist example that runs every 5 minutes.

### Scheduled (Linux cron)
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.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill clearly instructs users to copy and run a shell script, configure cron/LaunchAgent persistence, and invoke launchctl, yet it declares no tool scope or allowed-tools metadata. This increases the chance an agent or reviewer underestimates the skill's ability to execute host-level actions, including service restarts and scheduled execution.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The description presents health monitoring and auto-restart as routine behavior but does not prominently warn that stop/start operations can interrupt running services or affect availability. In operational environments, this can lead to unintended outages, restarts of the wrong service label, or unsafe execution by an agent without informed user consent.

Session Persistence

Medium
Category
Rogue Agent
Content
### 4. Set up automated scheduling (macOS LaunchAgent)

Create `~/Library/LaunchAgents/com.mcp-health-monitor.plist`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
Confidence
60% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
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.

Session Persistence

Medium
Category
Rogue Agent
Content
Load the agent:

```bash
launchctl load ~/Library/LaunchAgents/com.mcp-health-monitor.plist
```

### 5. Linux alternative (systemd timer or cron)
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.

Session Persistence

Medium
Category
Rogue Agent
Content
### 5. Linux alternative (systemd timer or cron)

```bash
# crontab -e
*/5 * * * * /path/to/mcp-healthcheck.sh
```
Confidence
85% 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.

External Transmission

Medium
Category
Data Exfiltration
Content
local message="$1"
  if [[ -n "$BOT_TOKEN" && -n "$CHAT_ID" ]]; then
    local http_code
    http_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
      "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
      -d chat_id="$CHAT_ID" \
      -d text="$message" \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
if [[ -n "$BOT_TOKEN" && -n "$CHAT_ID" ]]; then
    local http_code
    http_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
      "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
      -d chat_id="$CHAT_ID" \
      -d text="$message" \
      -d parse_mode="Markdown" 2>/dev/null || echo "000")
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.