T09 · Insecure Skill Coding Practices
Error
- Location
- skill.py:138
- Finding
- Bearer Token Transmitted over Unencrypted HTTP<![CDATA[ ## Vulnerability Details **File Location**: `skill.py:25-26`, `skill.py:125`, `skill.py:138`; insecure example at `env_template.txt:8` **Vulnerability Type**: Plaintext transmission of sensitive authentication credentials **Risk Level**: High ### Vulnerable Code ```python HA_BASE_URL = os.getenv("HA_BASE_URL", "http://127.0.0.1:8123/api") HA_BEARER_TOKEN = os.getenv("HA_BEARER_TOKEN", "UNCONFIGURED_SANDBOX_TOKEN") ``` ```python headers = {"Authorization": f"Bearer {HA_BEARER_TOKEN}", "Content-Type": "application/json"} ``` ```python requests.post(url, headers=headers, json=req_payload, timeout=5) ``` The supplied environment template also encourages plaintext HTTP: ```text HA_BASE_URL=http://homeassistant.local:8123/api ``` ### Technical Analysis When real actuation is enabled, the Skill places the long-lived Home Assistant bearer token in the HTTP `Authorization` header. Neither the implementation nor the supplied configuration template requires TLS. Consequently, a non-loopback Home Assistant endpoint can receive sensitive credentials over unencrypted HTTP. The local-network address check does not provide transport confidentiality or server authentication. Restricting a destination to a private network therefore does not prevent interception, ARP spoofing, malicious access points, DNS manipulation, or traffic modification by another compromised device on the same network. The outbound request is consistent with the declared smart-home actuation functionality and is disabled by default. However, transmitting a long-lived credential over plaintext HTTP exceeds the minimum safe privilege and confidentiality requirements for that function. ### Attack Path 1. An operator configures `HA_BASE_URL` using the documented plaintext `http://homeassistant.local:8123/api` format. 2. The operator supplies a valid long-lived `HA_BEARER_TOKEN`. 3. `S2_ENABLE_REAL_ACTUATION` is set to `True`. 4. A matching plan causes `SafeActuator.execute_timeline()` to e ...[truncated 883 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require `https://` for every non-loopback endpoint and reject insecure schemes during configuration validation. 2. Permit loopback HTTP only through an explicit development-only option that is disabled by default. 3. Configure `requests` to verify the server certificate; do not disable TLS verification. 4. Support a private certificate authority or certificate pinning where Home Assistant uses an internally issued certificate. 5. Replace the documented URL with an HTTPS example and clearly warn that bearer tokens must not traverse plaintext networks. 6. Use a dedicated, narrowly scoped Home Assistant credential rather than a broadly privileged administrator token. 7. Prevent redirects or validate every redirect destination before forwarding the Authorization header. 8. Add automated tests confirming that non-loopback HTTP URLs are rejected before any request is sent. ]]>
