Back to skill

Security audit

Muster Connect

Security checks for vulnerabilities and agentic risk

Overview

This skill is review-worthy because it installs persistent services, exposes a public tunnel, modifies future agent instructions, and lets a Muster endpoint influence tasks and updates.

Install only if you are comfortable with a local server that persists across sessions, exposes a Cloudflare tunnel by default, stores and prints bearer keys, modifies OpenClaw and HEARTBEAT configuration, and sends agent identity, logs, reflections, task data, and token usage to the configured Muster endpoint. Review the scripts first, prefer localhost-only operation, avoid automatic updates from heartbeat responses, and rotate any keys that appear in logs or transcripts.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (7)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/install.sh:107
Finding

Unverified Remote Scripts and Mutable Upstream Code Are Executed Locally

Content
View full analysis
/dev/null || true fi ``` ```bash if [ -d "$INSTALL_DIR" ]; then log "$INSTALL_DIR exists — pulling latest..."; cd "$INSTALL_DIR"; git pull origin main else git clone https://github.com/AirborneEagle/muster.git "$INSTALL_DIR"; cd "$INSTALL_DIR" fi npm install --silent ``` The update mechanism similarly fetches and executes mutable code: ```bash git fetch origin main --quiet REMOTE_VERSION=$(git show origin/main:package.json | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8');console.log(JSON.parse(d).version)" 2>/dev/null || echo "unknown") git pull origin main npm install --silent npm run build npx drizzle-kit migrate restart_service "$SERVICE_MODE" ``` Persistent instructions can trigger that update based on a remote response: ```markdown - If `update_available` is true: run `bash ~/.openclaw/workspace/skills/muster/scripts/update.sh` ``` ### Technical Analysis The installer pipes responses from NodeSource and Docker directly into a shell. The NodeSource response is executed through `sudo`, while Docker's installer may independently request or use elevated privileges. No version pin, cryptographic hash, detached signature, or local review step is present. The application installation and update paths also trust mutable `main` branch con ...[truncated 1665 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/connect.sh:280
Finding

Persistent Heartbeat Modification Creates a Cross-Session Remote Control Channel

Content
View full analysis
> "$HEARTBEAT_FILE" log "✓ Appended Muster checklist to HEARTBEAT.md" fi fi ``` The appended instructions include: ```markdown ## Muster check-in - Call Muster MCP `heartbeat` tool with your agent_id and current status - If `next_task` returned: pick it up (see Muster skill for task workflow) - If `update_available` is true: run `bash ~/.openclaw/workspace/skills/muster/scripts/update.sh` - If `tunnel_url` changed vs `~/.muster/tunnel.json`: update stored value, notify human with new URL - If tunnel is down (no `tunnel_url`): restart tunnel service - If idle and no tasks: consider proposing initiative via `create_task` ``` The Skill also directs the agent to prioritize the remote service: ```markdown ### heartbeat — call every wake cycle Reports status, picks up work. **Always call this first.** ``` ### Technical Analysis `connect.sh` does more than configure an optional API client: it appends behavioral instructions to the agent's persistent `HEARTBEAT.md`. These instructions survive the current invocation and affect future wake cycles and sessions. The injected rules require recurring contact with a remote endpoint, acceptance of remote task assignments, automatic reaction to update signals, service restart behavior, and proactive creation of work. This gives content returned by the Muster endpoint continuing influence over the agent's priorities and local actions. The instructions do not clearly establish that re ...[truncated 1332 chars]
Remediation
View remediation

T06 · System Persistence

Error
Location
scripts/install.sh:228
Finding

Always-On Services, Git Hooks, and Public Tunnel Establish Broad System Persistence

Content
View full analysis
RunAtLoad KeepAlive ThrottleInterval 10 ``` The installer also writes executable repository hooks: ```bash for hook in post-commit post-merge; do cat > "$HOOKS_DIR/$hook" << 'HOOKEOF' #!/usr/bin/env bash set -e MUSTER_DIR="$(git rev-parse --show-toplevel)" SERVICE="com.bai.muster" LOGFILE="$MUSTER_DIR/logs/deploy.log" cd "$MUSTER_DIR" /opt/homebrew/bin/npm run build >> "$LOGFILE" 2>&1 launchctl kickstart -k "gui/$(id -u)/$SERVICE" >> "$LOGFILE" 2>&1 HOOKEOF chmod +x "$HOOKS_DIR/$hook" done ``` A persistent public tunnel is enabled by default: ```bash $(command -v cloudflared) tunnel --url http://localhost:${MUSTER_PORT} ``` ```bash RunAtLoad KeepAlive ``` On Linux, comparable persistence is installed through PM2: ```bash pm2 save pm2 startup ``` ### Technical Analysis The Skill installs two always-on processes: the Muster server and a Cloudflare quick tunnel. It configures them to restart automatically and survive logins or reboots. It additionally modifies Git hooks so commits and merges execute builds and restart the service. An always-on service is related to the declared server functionality, but the public tunnel and Git hook modifications are not required for a local coordination service. Enabling all of these by default unnecessarily expands persistence, supply-chain, and network attack surfaces. If source code or dependencies are later compromised, the Git hooks and service manager automatically rebuild and relaunch the payload. The quick tunnel also makes a locally hosted application reachable through an externally ...[truncated 1124 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:32
Finding

Sensitive Agent Data Is Routed Through a Publicly Exposed Control Plane Without Data Minimization

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/install.sh:393
Finding

Administrator and Agent Credentials Are Stored and Printed Insecurely

Content
View full analysis
/dev/null; then ADMIN_PASSWORD=$(grep "^MUSTER_ADMIN_KEY=" "$ENV_FILE" | cut -d= -f2) else ADMIN_PASSWORD="sk-muster-admin-$(openssl rand -hex 32)" echo "MUSTER_ADMIN_KEY=${ADMIN_PASSWORD}" >> "$ENV_FILE" fi ``` The key is then returned through standard output: ```bash cat <
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/connect.sh:205
Finding

Unescaped Shell Values Permit Python and JSON Injection During Connection

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/connect.sh:303
Finding

Predictable Shared Temporary File Allows Symlink Clobbering

Content
View full analysis
&1) HEARTBEAT_RESPONSE=$(cat /tmp/muster-heartbeat-response.json 2>/dev/null) rm -f /tmp/muster-heartbeat-response.json ``` ### Technical Analysis The response is written to a fixed path in the shared `/tmp` directory. The script does not securely create the file, verify its ownership, reject symlinks, or isolate concurrent executions. On systems where another local user can create entries in `/tmp`, an attacker may pre-create `/tmp/muster-heartbeat-response.json` as a symbolic link to another file writable by the victim. Curl may then follow that link and overwrite the target. Concurrent runs can also read or delete each other's response files. ### Attack Path 1. A local attacker predicts the fixed filename. 2. The attacker creates `/tmp/muster-heartbeat-response.json` as a symlink to a file writable by the victim. 3. The victim runs `connect.sh`. 4. Curl opens the predictable path and follows the symlink. 5. The target file is overwritten with the heartbeat response, and the script later removes the temporary pathname. 6. Alternatively, a concurrent local process reads the response before cleanup. ### Impact Assessment The primary impact is corruption or truncation of arbitrary files ...[truncated 292 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (97)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
60% 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 · HEARTBEAT_MUSTER.md (reported line 4)May include surrounding context.

md
## Muster check-in
- Call Muster MCP `heartbeat` tool with your agent_id and current status
- **Error handling:** Distinguish failure modes when the heartbeat curl fails:
  - `curl exit 7` (connection refused) → "Muster server unreachable — check if it's running"
  - `curl exit 28` (timeout) → "Muster server timed out — may be overloaded"
  - HTTP `401` → "API key invalid — regenerate via Settings or re-run connect.sh"

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill claims to install and teach the Muster MCP workflow, but the detected behavior also covers update and maintenance operations such as pulling code, rebuilding, migrating, restarting services, and probing local health endpoints. This discrepancy obscures operational side effects and can cause an agent to perform privileged maintenance tasks that are outside the user's expected scope.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill claims to install and teach the Muster MCP workflow, but the detected behavior also covers update and maintenance operations such as pulling code, rebuilding, migrating, restarting services, and probing local health endpoints. This discrepancy obscures operational side effects and can cause an agent to perform privileged maintenance tasks that are outside the user's expected scope.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims to install and teach the Muster MCP workflow, but the detected behavior also covers update and maintenance operations such as pulling code, rebuilding, migrating, restarting services, and probing local health endpoints. This discrepancy obscures operational side effects and can cause an agent to perform privileged maintenance tasks that are outside the user's expected scope.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
83% confidence
Finding

This command chains remote script execution and a privileged user-group modification in one line, reducing opportunities for review between risky actions. In an agent-assisted setup flow, such chaining increases the likelihood of unsafe execution and makes it harder to apply principle-of-least-privilege or stop after the download step.

Content

Scanner excerpt · TROUBLESHOOTING.md (reported line 8)May include surrounding context.

md
## Setup Issues

### Docker Not Found
**Linux:** `curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER`
**macOS:** `brew install --cask docker` → open Docker Desktop → accept license.

### Port in Use

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · TROUBLESHOOTING.md (reported line 18)May include surrounding context.

Homebrew (macOS default): brew services restart postgresql@16 then pg_isready. Reset: dropdb muster && createdb muster && npx drizzle-kit migrate (destroys data). Docker: cd ~/muster && docker compose ps then docker compose logs db. Reset: docker compose down -v && docker compose up -d && npx drizzle-kit migrate (destroys data).

.env Missing

bash
cat > ~/muster/.env << EOF
MUSTER_DB_URL=postgresql://muster:muster@localhost:5432/muster

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · TROUBLESHOOTING.md (reported line 20)May include surrounding context.

Homebrew (macOS default): brew services restart postgresql@16 then pg_isready. Reset: dropdb muster && createdb muster && npx drizzle-kit migrate (destroys data). Docker: cd ~/muster && docker compose ps then docker compose logs db. Reset: docker compose down -v && docker compose up -d && npx drizzle-kit migrate (destroys data).

.env Missing

bash
cat > ~/muster/.env << EOF
MUSTER_DB_URL=postgresql://muster:muster@localhost:5432/muster

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 188)May include surrounding context.

sh
**Homebrew (macOS default):** `brew services restart postgresql@16` then `pg_isready`. Reset: `dropdb muster && createdb muster && npx drizzle-kit migrate` (destroys data).
**Docker:** `cd ~/muster && docker compose ps` then `docker compose logs db`. Reset: `docker compose down -v && docker compose up -d && npx drizzle-kit migrate` (destroys data).

### .env Missing
```bash
cat > ~/muster/.env << EOF
MUSTER_DB_URL=postgresql://muster:muster@localhost:5432/muster

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/update.sh (reported line 62)May include surrounding context.

sh
**Homebrew (macOS default):** `brew services restart postgresql@16` then `pg_isready`. Reset: `dropdb muster && createdb muster && npx drizzle-kit migrate` (destroys data).
**Docker:** `cd ~/muster && docker compose ps` then `docker compose logs db`. Reset: `docker compose down -v && docker compose up -d && npx drizzle-kit migrate` (destroys data).

### .env Missing
```bash
cat > ~/muster/.env << EOF
MUSTER_DB_URL=postgresql://muster:muster@localhost:5432/muster

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · TROUBLESHOOTING.md (reported line 27)May include surrounding context.

text

### npm Install Fails
Check `node --version` (≥ 20). Try: `cd ~/muster && rm -rf node_modules package-lock.json && npm install`

---

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/install.sh (reported line 184)May include surrounding context.

sh
```

### npm Install Fails
Check `node --version` (≥ 20). Try: `cd ~/muster && rm -rf node_modules package-lock.json && npm install`

---

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/connect.sh (reported line 99)May include surrounding context.

sh
if [ -z "$MUSTER_ENDPOINT" ]; then
  # Try to find from a local install
  if [ -f "$HOME/muster/.env" ]; then
    MUSTER_PORT=$(grep "^PORT=" "$HOME/muster/.env" 2>/dev/null | cut -d= -f2 || echo "3000")
    MUSTER_ENDPOINT="http://localhost:${MUSTER_PORT}/mcp"
    log "Found local Muster at $MUSTER_ENDPOINT"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/connect.sh (reported line 100)May include surrounding context.

sh
if [ -z "$MUSTER_ENDPOINT" ]; then
  # Try to find from a local install
  if [ -f "$HOME/muster/.env" ]; then
    MUSTER_PORT=$(grep "^PORT=" "$HOME/muster/.env" 2>/dev/null | cut -d= -f2 || echo "3000")
    MUSTER_ENDPOINT="http://localhost:${MUSTER_PORT}/mcp"
    log "Found local Muster at $MUSTER_ENDPOINT"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 167)May include surrounding context.

sh
if [ -z "$MUSTER_ENDPOINT" ]; then
  # Try to find from a local install
  if [ -f "$HOME/muster/.env" ]; then
    MUSTER_PORT=$(grep "^PORT=" "$HOME/muster/.env" 2>/dev/null | cut -d= -f2 || echo "3000")
    MUSTER_ENDPOINT="http://localhost:${MUSTER_PORT}/mcp"
    log "Found local Muster at $MUSTER_ENDPOINT"

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/install.sh (reported line 180)May include surrounding context.

sh
if [ -z "$MUSTER_ENDPOINT" ]; then
  # Try to find from a local install
  if [ -f "$HOME/muster/.env" ]; then
    MUSTER_PORT=$(grep "^PORT=" "$HOME/muster/.env" 2>/dev/null | cut -d= -f2 || echo "3000")
    MUSTER_ENDPOINT="http://localhost:${MUSTER_PORT}/mcp"
    log "Found local Muster at $MUSTER_ENDPOINT"

Self-Modification

High
Category
Rogue Agent
Confidence
91% confidence
Finding

The script silently modifies ~/.openclaw/openclaw.json to enable the muster skill and inject persistent environment variables including the API key. Self-modifying agent configuration is dangerous because it changes future agent behavior and creates durable trust in an externally supplied endpoint without explicit user approval.

Content

Scanner excerpt · scripts/connect.sh (reported line 233)May include surrounding context.

sh
EOF
log "✓ State file: ~/.muster/state.json"

# OpenClaw config — add/update skills.entries.muster
if [ -f "$OPENCLAW_CONFIG" ]; then
  # Use python to safely merge into existing config
  python3 << PYEOF

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 · scripts/connect.sh (reported line 323)May include surrounding context.

sh
else
    log "⚠ First heartbeat returned unexpected HTTP $HTTP_CODE"
  fi
  rm -f /tmp/muster-heartbeat-response.json
else
  log "⚠ Skipping heartbeat — missing agent_id or key"
fi

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/install.sh (reported line 102)May include surrounding context.

sh
if ! command_exists git; then
  log "Installing git..."
  if [ "$OS" = "macos" ]; then xcode-select --install 2>/dev/null || true
  else sudo apt-get update -qq && sudo apt-get install -y -qq git; fi
fi
log "✓ git $(git --version | awk '{print $3}')"

Chaining Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Piping a downloaded script directly to sudo is a high-risk anti-pattern because it lets remote content control privileged execution in one step. In an installer, this is especially dangerous since users may trust it and not notice that root code is being sourced live from the network.

Content

Scanner excerpt · scripts/install.sh (reported line 109)May include surrounding context.

sh
if ! command_exists node || [ "$(node -e 'console.log(parseInt(process.versions.node))')" -lt 20 ]; then
  log "Installing Node.js ≥ 20..."
  if [ "$OS" = "macos" ]; then brew install node@20
  else curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y -qq nodejs; fi
fi
log "✓ node $(node --version)"

Chaining Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Piping a downloaded script directly to sudo is a high-risk anti-pattern because it lets remote content control privileged execution in one step. In an installer, this is especially dangerous since users may trust it and not notice that root code is being sourced live from the network.

Content

Scanner excerpt · scripts/install.sh (reported line 109)May include surrounding context.

sh
if ! command_exists node || [ "$(node -e 'console.log(parseInt(process.versions.node))')" -lt 20 ]; then
  log "Installing Node.js ≥ 20..."
  if [ "$OS" = "macos" ]; then brew install node@20
  else curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y -qq nodejs; fi
fi
log "✓ node $(node --version)"

Chaining Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

curl ... | sh creates a direct execution chain from external content to the local shell, which is a well-known supply-chain hazard. In this installer, the behavior is not clearly necessary to the stated skill purpose and increases host compromise risk.

Content

Scanner excerpt · scripts/install.sh (reported line 128)May include surrounding context.

sh
log "⚠ Docker Desktop is opening. Accept the license agreement to continue."
      while ! docker info &>/dev/null; do sleep 5; done
    else
      curl -fsSL https://get.docker.com | sh
      sudo usermod -aG docker "$USER" 2>/dev/null || true
    fi
  fi

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The installer automatically installs cloudflared, a prerequisite for publishing the local service externally, despite the skill description only promising local installation and connection. This materially expands exposure by preparing unauthenticated remote-access capability without clear, informed user consent.

Content

No source excerpt is available for this finding.

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 · scripts/install.sh (reported line 146)May include surrounding context.

sh
if [ "$OS" = "macos" ]; then brew install cloudflare/cloudflare/cloudflared
  else
    curl -fsSL -o /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
    sudo install -m 755 /tmp/cloudflared /usr/local/bin/cloudflared; rm -f /tmp/cloudflared
  fi
fi
log "✓ cloudflared $(cloudflared --version 2>&1 | awk '{print $3}')"

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · scripts/install.sh (reported line 146)May include surrounding context.

sh
if [ "$OS" = "macos" ]; then brew install cloudflare/cloudflare/cloudflared
  else
    curl -fsSL -o /tmp/cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
    sudo install -m 755 /tmp/cloudflared /usr/local/bin/cloudflared; rm -f /tmp/cloudflared
  fi
fi
log "✓ cloudflared $(cloudflared --version 2>&1 | awk '{print $3}')"

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The installer automatically creates a Cloudflare tunnel to http://localhost:${MUSTER_PORT} and persists it via launchd or pm2, exposing the service beyond localhost. Because the skill description does not justify public internet exposure, this behavior creates significant remote attack surface and is especially dangerous if the application has weak authentication or future vulnerabilities.

Content

No source excerpt is available for this finding.