T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/homebridge_api.py:50
- Finding
- Homebridge credentials and bearer tokens may be transmitted over unencrypted HTTP<![CDATA[ ## Vulnerability Details **File Location**: `scripts/homebridge_api.py:50-78` and `scripts/homebridge_api.py:174-181` **Vulnerability Type**: Missing HTTPS enforcement for sensitive authentication traffic **Risk Level**: High ### Vulnerable Code ```python def make_request(url: str, method: str = "GET", data: dict = None, token: str = None) -> dict: """Make HTTP request to Homebridge API.""" headers = {"Content-Type": "application/json"} if token: headers["Authorization"] = f"Bearer {token}" body = json.dumps(data).encode() if data else None req = Request(url, data=body, headers=headers, method=method) try: with urlopen(req, timeout=30) as resp: return json.loads(resp.read().decode()) except HTTPError as e: error_body = e.read().decode() if e.fp else "" print(f"HTTP Error {e.code}: {e.reason}", file=sys.stderr) if error_body: print(f"Response: {error_body}", file=sys.stderr) sys.exit(1) except URLError as e: print(f"Connection error: {e.reason}", file=sys.stderr) sys.exit(1) def authenticate(base_url: str, username: str, password: str) -> str: """Authenticate and return access token.""" url = f"{base_url}/api/auth/login" data = {"username": username, "password": password} response = make_request(url, method="POST", data=data) return response.get("access_token") ``` The configured URL is used without validating its scheme: ```python config = load_config() base_url = config["url"].rstrip("/") username = config["username"] password = config["password"] # Authenticate token = authenticate(base_url, username, password) ``` ### Technical Analysis The script reads an administrative username and password from `~/.clawdbot/credentials/homebridge.json` and sends them to the configured Homebridge URL. After authentication, it sends the returned bearer token in the `Authorization` header on subsequent API requests. ...[truncated 2564 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require HTTPS before loading or transmitting credentials.** Parse and validate the configured URL before authentication: ```python from urllib.parse import urlsplit def validate_base_url(raw_url: str) -> str: url = raw_url.rstrip("/") parsed = urlsplit(url) if parsed.scheme.lower() != "https": raise ValueError("Homebridge URL must use HTTPS") if not parsed.hostname: raise ValueError("Homebridge URL must include a valid hostname") if parsed.username or parsed.password: raise ValueError("Credentials must not be embedded in the URL") return url ``` Apply it when reading the configuration: ```python try: base_url = validate_base_url(config["url"]) except ValueError as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1) ``` 2. **Do not silently fall back to HTTP.** If plaintext access is required for a narrowly defined loopback-only deployment, require an explicit insecure opt-in and restrict it to verified loopback addresses. Display a prominent warning. Plaintext access to LAN or remote hosts should remain prohibited. 3. **Preserve TLS certificate verification.** Do not use an unverified SSL context. For local deployments using a private or self-signed certificate, support a configurable trusted CA certificate instead of disabling verification. 4. **Use a least-privileged Homebridge account.** The configured account should have only the API permissions required to enumerate and control intended accessories, where supported. 5. **Protect the credential file.** Require or warn when `~/.clawdbot/credentials/homebridge.json` is readable by group or other users. Recommended permissions are `0600`, with the parent credentials directory restricted to the owning user. 6. **Limit sensitive error output.** Avoid printing arbitrary authentication response bodies because a server or intermediary could retu ...[truncated 257 chars]
