T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/diagnose.sh:14
- Finding
- Unrestricted destination URLs allow BlueBubbles credential disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/diagnose.sh:14-19, 61, 77, 107-111, 133-155`; `scripts/reset-webhook.sh:13-18, 34-43, 56, 107-111, 128` **Vulnerability Type**: Unvalidated credential destination and plaintext credential transmission **Risk Level**: High ### Complete Code Snippet From `scripts/diagnose.sh`: ```bash while [[ $# -gt 0 ]]; do case $1 in --bb-url) BB_URL="$2"; shift 2 ;; --password) BB_PASSWORD="$2"; shift 2 ;; --webhook-url) OPENCLAW_WEBHOOK_URL="$2"; shift 2 ;; --quiet|-q) QUIET=1; shift ;; --json) JSON_OUTPUT=1; shift ;; *) echo "Unknown arg: $1"; exit 1 ;; esac done ``` ```bash HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 -H "Authorization: Bearer ${BB_PASSWORD}" "${BB_URL}/api/v1/ping" 2>/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
- <![CDATA[ ## Remediation Suggestions 1. Enforce loopback-only destinations by default: - Resolve the hostname and require every resolved address to be `127.0.0.0/8` or `::1`. - Do not rely only on string comparisons such as checking for `localhost`. 2. Reject non-HTTPS remote URLs. If remote operation is genuinely required, require an explicit opt-in and interactive confirmation. 3. Maintain an allowlist of expected URL schemes, hosts, ports, and paths. 4. Do not send the BlueBubbles API password to the OpenClaw webhook endpoint during a health probe unless that exact authentication protocol is required. 5. Use a separate, narrowly scoped webhook secret instead of reusing the BlueBubbles administrative/API password. 6. Avoid query-string credentials. Prefer an authentication header or signed webhook mechanism because URLs are commonly stored in logs, databases, and diagnostic output. 7. Refuse redirects or constrain them to the validated origin by using `curl --max-redirs 0`, unless redirects are explicitly required. 8. Update the documentation to accurately state the enforced network policy and warn users before any remote configuration is accepted. ]]>
