Back to skill

Security audit

Bluebubbles Healthcheck

Security checks for vulnerabilities and agentic risk

Overview

This skill has a legitimate troubleshooting purpose, but its repair path can delete webhook settings and expose the BlueBubbles password if used with unsafe URLs or logs.

Review this carefully before installing. Use diagnose.sh only for read-only checks unless you are prepared for heal.sh/reset-webhook.sh to restart the gateway and replace BlueBubbles webhook configuration. Do not run it on a BlueBubbles server with other webhook integrations, do not pass remote BB_URL or OPENCLAW_WEBHOOK_URL values, and rotate BB_PASSWORD if prior runs may have exposed password-bearing webhook URLs in logs or transcripts.

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
scripts/diagnose.sh:14
Finding

Unrestricted destination URLs allow BlueBubbles credential disclosure

Content
View full analysis
/dev/null || echo "000") ``` ```bash ENDPOINT_RESPONSE=$(curl -s -X POST --max-time 5 \ -H "Authorization: Bearer ${BB_PASSWORD}" \ -H "Content-Type: application/json" \ -d '{"type":"ping","data":{}}' \ "${OPENCLAW_WEBHOOK_URL}" 2>/dev/null || echo "") ``` From `scripts/reset-webhook.sh`: ```bash # Build full webhook URL with password (for BB to call OpenClaw) # Note: The password is included in the registered URL so BB can authenticate with OpenClaw if [[ "$OPENCLAW_WEBHOOK_URL" == *"password="* ]]; then FULL_WEBHOOK_URL="$OPENCLAW_WEBHOOK_URL" else if [[ "$OPENCLAW_WEBHOOK_URL" == *"?"* ]]; then FULL_WEBHOOK_URL="${OPENCLAW_WEBHOOK_URL}&password=${BB_PASSWORD}" else FULL_WEBHOOK_URL="${OPENCLAW_WEBHOOK_URL}?password=${BB_PASSWORD}" fi fi ``` ```bash REGISTER_RESULT=$(curl -s -X POST --max-time 10 \ -H "Authorization: Bearer ${BB_PASSWORD}" \ -H "Content-Type: application/json" \ -d "{\"url\": \"${ESCAPED_URL}\", \"events\": [\"*\"]}" \ "${BB_URL}/api/v1/webhook" 2>/dev/null) ``` ### Technical Analysis The scripts accept `BB_URL` and `OPENCLAW_WEBHOOK_URL` from environment variables or command-line arguments without validating the destination ...[truncated 2254 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/diagnose.sh:77
Finding

Diagnostic output discloses credentials contained in registered webhook URLs

Content
View full analysis
/dev/null || echo "{}") # Extract webhook URLs using Python (portable JSON parsing) WEBHOOK_URLS=$(echo "$WEBHOOK_RESPONSE" | python3 -c " import sys, json try: d = json.load(sys.stdin) for w in d.get('data', []): print(w.get('url', '')) except: pass " 2>/dev/null) # Check if any webhook points to OpenClaw (port 18789) if echo "$WEBHOOK_URLS" | grep -q "18789"; then MATCHING_URL=$(echo "$WEBHOOK_URLS" | grep "18789" | head -1) check_pass "webhook_registered" "$MATCHING_URL" ``` The selected URL is passed to: ```bash check_pass() { local name="$1" local detail="${2:-}" log "✅ CHECK $name: PASS${detail:+ ($detail)}" RESULTS+=("{\"check\":\"$name\",\"status\":\"pass\",\"detail\":\"$detail\"}") } ``` ### Technical Analysis BlueBubbles webhook URLs may include the password in the query string, as created by `reset-webhook.sh`. The diagnostic script extracts the complete registered URL and passes it directly to `check_pass` without redaction. The unredacted URL is emitted in normal terminal output and is also interpolated into the `RESULTS` array used by JSON output. This directly contradicts the documentation’s claim that the password is masked in all script output. The exposure is especially significant in an Agent environment because command output may be copied into conversation history, execution traces, centralized logs, monitoring systems, or support reports. The JSON construction also performs no proper JSON escaping, which can produce malformed output for unusual URL content, although the confirmed security issue here is secret disclosure. ### Attack Path 1. `reset-webhook.sh` or anot ...[truncated 1102 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/reset-webhook.sh:68
Finding

Webhook repair deletes all registrations and creates an overbroad wildcard subscription

Content
View full analysis
/dev/null) DELETED=0 if [[ -n "$IDS" ]]; then while IFS= read -r id; do if [[ -n "$id" ]]; then log "Deleting webhook id=$id" curl -s -X DELETE --max-time 10 -H "Authorization: Bearer ${BB_PASSWORD}" "${BB_URL}/api/v1/webhook/${id}" > /dev/null 2>&1 ((DELETED++)) fi done <<< "$IDS" log "Deleted $DELETED webhook(s)" else log "No existing webhooks to delete" fi ``` ```bash # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ # Step 4: Register new webhook # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ log "Registering new webhook..." # Escape the URL for JSON ESCAPED_URL=$(echo "$FULL_WEBHOOK_URL" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read().strip()))" | sed 's/^"//;s/"$//') REGISTER_RESULT=$(curl -s -X POST --max-time 10 \ -H "Authorization: Bearer ${BB_PASSWORD}" \ -H "Content-Type: application/json" \ -d "{\"url\": \"${ESCAPED_URL}\", \"events\": [\"*\"]}" \ "${BB_URL}/api/v1/webhook" 2>/dev/null) ``` ### Technical Analysis The declared task is to repair the BlueBubbles-to-OpenClaw webhook. However, the reset implementation enumerates every registered webhook ID and deletes all of them without checking the destination, owner, path, event set, or whether the registration belongs to OpenClaw. It then creates one new webhook subscrib ...[truncated 1923 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/heal.sh:47
Finding

Auto-healing masks diagnostic failures and reports false success

Content
View full analysis
&1) || true DIAGNOSE_EXIT=$? echo "$DIAGNOSE_OUTPUT" if [[ "$DIAGNOSE_EXIT" == "0" ]]; then log "" log "✅ All checks passed — no healing needed" exit 0 fi ``` Verification uses the same pattern: ```bash VERIFY_OUTPUT=$("${SCRIPT_DIR}/diagnose.sh" 2>&1) || true VERIFY_EXIT=$? ``` ### Technical Analysis The command list: ```bash DIAGNOSE_OUTPUT=$(...) || true ``` returns the exit status of `true` whenever `diagnose.sh` fails. The following assignment therefore records zero in `DIAGNOSE_EXIT`, not the diagnostic script’s nonzero status. As a result, failed diagnostics enter the branch that prints “All checks passed” and exits successfully. The same defect affects post-healing verification, allowing failed verification to be interpreted as successful. This is a security-relevant reliability flaw because health monitoring and automatic recovery depend on accurate status propagation. It can suppress recovery during a real connectivity outage and mislead users or supervising Agents into believing the integration is healthy. ### Attack Path 1. A real failure occurs, such as the BlueBubbles server becoming unavailable, the OpenClaw endpoint failing, or webhook delivery stopping. 2. `diagnose.sh` emits failed checks and exits with a nonzero status. 3. The `|| true` clause executes and returns zero. 4. `DIAGNOSE_EXIT=$?` stores zero. 5. `heal.sh` prints the diagnostic text but immediately enters the “All checks passed” branch. 6. No gateway restart or webhook repair occurs. 7. Scheduled automation, heartbeat monitoring, or an Agent receives a successful process exit code and may report a healthy state. 8. If the same pattern i ...[truncated 757 chars]
Remediation
View remediation
&1); then DIAGNOSE_EXIT=0 else DIAGNOSE_EXIT=$? fi ``` Apply the same correction to verification: ```bash if VERIFY_OUTPUT=$("${SCRIPT_DIR}/diagnose.sh" 2>&1); then VERIFY_EXIT=0 else VERIFY_EXIT=$? fi ``` Additional hardening steps: 1. Add automated tests where `diagnose.sh` exits with zero and several nonzero values. 2. Assert that healing actions execute only for the relevant failed checks. 3. Verify that failed post-healing diagnostics result in a nonzero final exit status. 4. Prefer structured diagnostic output over parsing human-readable lines with `grep`. 5. Do not suppress failures from `openclaw gateway restart` or `reset-webhook.sh`; capture and report their statuses explicitly. 6. Ensure the final success result requires both successful remediation commands and successful verification. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This mismatch includes a materially important undeclared destructive behavior: deleting all existing BlueBubbles webhooks and replacing them. Undisclosed destructive actions can cause denial of service, break other integrations, or overwrite intended configuration, especially when users think they are running a bounded connectivity healthcheck.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

This mismatch includes a materially important undeclared destructive behavior: deleting all existing BlueBubbles webhooks and replacing them. Undisclosed destructive actions can cause denial of service, break other integrations, or overwrite intended configuration, especially when users think they are running a bounded connectivity healthcheck.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This mismatch includes a materially important undeclared destructive behavior: deleting all existing BlueBubbles webhooks and replacing them. Undisclosed destructive actions can cause denial of service, break other integrations, or overwrite intended configuration, especially when users think they are running a bounded connectivity healthcheck.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% 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 · references/bluebubbles-api.md (reported line 48)May include surrounding context.

Delete Webhook

text
DELETE /api/v1/webhook/:id

Removes webhook by ID. Use to clear broken registrations before re-registering.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest says the skill 'diagnoses and auto-heals' and specifically claims it 'auto-fixes webhook backoff, stale registrations, and gateway issues.' In this file, the script only performs four read-oriented checks, reports pass/fail, and exits with status; it never invokes any BlueBubbles or OpenClaw API to modify webhook state, clear registrations, reset backoff, or restart/repair a gateway.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/diagnose.sh (reported line 155)May include surrounding context.

sh
" 2>/dev/null)

  # Also check if there are any recent messages (proxy for activity)
  MSG_COUNT=$(curl -s --max-time 5 -H "Authorization: Bearer ${BB_PASSWORD}" "${BB_URL}/api/v1/message/count" 2>/dev/null | python3 -c "
import sys, json
try:
    d = json.load(sys.stdin)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/reset-webhook.sh (reported line 85)May include surrounding context.

sh
while IFS= read -r id; do
    if [[ -n "$id" ]]; then
      log "Deleting webhook id=$id"
      curl -s -X DELETE --max-time 10 -H "Authorization: Bearer ${BB_PASSWORD}" "${BB_URL}/api/v1/webhook/${id}" > /dev/null 2>&1
      ((DELETED++))
    fi
  done <<< "$IDS"

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

sh
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sleep 1

VERIFY=$(curl -s --max-time 10 -H "Authorization: Bearer ${BB_PASSWORD}" "${BB_URL}/api/v1/webhook" 2>/dev/null)
COUNT=$(echo "$VERIFY" | python3 -c "import sys,json; d=json.load(sys.stdin); print(len(d.get('data',[])))" 2>/dev/null || echo "0")

log "Webhook count after reset: $COUNT"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README describes auto-heal behavior that can restart services and delete all existing webhooks, but it does not prominently warn that these are destructive configuration changes. This is dangerous because operators or agents may run the skill expecting a safe health check, while the healing path can disrupt active integrations or remove intentionally configured webhook state.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manual trigger phrases are very broad and map to ordinary troubleshooting requests, which can cause the agent to invoke a skill that performs operational changes when the user may only be asking for diagnosis or advice. In this skill’s context, that ambiguity is more dangerous because the documented behavior includes auto-healing actions such as restarting the gateway and deleting/re-registering webhooks.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill explicitly instructs users to run shell scripts that can restart services and modify webhook configuration, but it declares no tool scope or permissions boundary. In an agent ecosystem, missing an explicit shell/tool declaration increases the chance the skill is invoked with broader-than-expected execution capability and without adequate user review of destructive actions.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

Encouraging periodic healthchecks in a skill that also advertises auto-healing increases the risk of unattended execution of disruptive actions such as service restarts and webhook resets. In agentic environments, broad recurring triggers can turn a maintenance script into an automated configuration mutator without incident-specific human intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The Auto-Heal instructions describe operations that may restart the gateway and delete/re-register webhooks, but they do not prominently warn about service disruption or side effects before the command is presented. Users may execute the command expecting a harmless healthcheck and inadvertently interrupt messaging or remove other webhook integrations.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/troubleshooting.md (reported line 9)May include surrounding context.

md
## Issue: BB Server Unreachable

**Symptom:** `diagnose.sh` fails at health check, curl to `/api/v1/ping` times out.

**Causes:**
- BlueBubbles app not running on Mac

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The troubleshooting guide instructs operators to delete and recreate a webhook, which changes server state and can temporarily disrupt integrations if performed incorrectly. In an operational skill that may be followed quickly during incident response, omitting an explicit warning, prerequisites, or confirmation step increases the chance of accidental service impact or misconfiguration.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This POST transmits a sensitive Bearer token to an external endpoint defined by configuration, so a malicious or compromised webhook target can capture it. In this skill context, the danger is increased because the endpoint is user-configurable and not constrained to localhost or a trusted allowlist.

Content

Scanner excerpt · scripts/diagnose.sh (reported line 107)May include surrounding context.

sh
log "─── CHECK 3: OpenClaw webhook endpoint alive ───"

# Test OpenClaw webhook endpoint with Authorization header
ENDPOINT_RESPONSE=$(curl -s -X POST --max-time 5 \
  -H "Authorization: Bearer ${BB_PASSWORD}" \
  -H "Content-Type: application/json" \
  -d '{"type":"ping","data":{}}' \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script sends the BlueBubbles bearer token in an Authorization header to the configured webhook URL, which may be remote or attacker-controlled if the URL is misconfigured. That unnecessarily discloses a sensitive credential to a second service and could allow reuse of the token against the BlueBubbles API.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
83% confidence
Finding

The script transmits sensitive data to an external service by embedding BB_PASSWORD into the webhook URL and then sending that URL to the BlueBubbles server for storage and later use. Query-string secrets are commonly exposed via logs, admin UIs, proxies, crash reports, and webhook listings, so this creates a real credential leakage risk even though the network call itself is expected behavior for this skill.

Content

Scanner excerpt · scripts/reset-webhook.sh (reported line 107)May include surrounding context.

sh
# Escape the URL for JSON
ESCAPED_URL=$(echo "$FULL_WEBHOOK_URL" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read().strip()))" | sed 's/^"//;s/"$//')

REGISTER_RESULT=$(curl -s -X POST --max-time 10 \
  -H "Authorization: Bearer ${BB_PASSWORD}" \
  -H "Content-Type: application/json" \
  -d "{\"url\": \"${ESCAPED_URL}\", \"events\": [\"*\"]}" \

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script requires BB_PASSWORD via argument or environment variable and uses it across multiple authenticated requests. While it errors if the value is missing, there is no clear warning or explanatory usage text telling the user that a sensitive credential will be consumed and sent in outbound requests during diagnostics.

Content

No source excerpt is available for this finding.