T09 · Insecure Skill Coding Practices
- Location
shelly_client.py:10- Finding
Home Assistant bearer token transmitted to an unvalidated endpoint without mandatory TLS
- Content
View full analysis
Vulnerability Details
File Location:
shelly_client.py, lines 10–11, 41–65, and 97–109
Vulnerability Type: Sensitive credential exposure through an unvalidated network destination and insecure transport
Risk Level: HighVulnerable Code
python HA_URL = os.getenv("HOME_ASSISTANT_URL") HA_TOKEN = os.getenv("SUPER_SECRET_HA_TOKEN")python def trigger_home_assistant(entity_id: str, state: str) -> dict: """Toggle a Home Assistant entity.""" if not HA_URL or not HA_TOKEN: return {"status": "error", "message": "Home Assistant credentials not configured"} headers = { "Authorization": f"Bearer {HA_TOKEN}", "Content-Type": "application/json" } service = "homeassistant.turn_on" if state == "on" else "homeassistant.turn_off" domain = entity_id.split(".")[0] try: response = requests.post( f"{HA_URL}/api/services/{service}", headers=headers, json={"entity_id": entity_id}, timeout=10 ) response.raise_for_status() return {"status": "success", "action": f"{domain} turned {state}"} except Exception as e: return {"status": "error", "message": str(e)}python if metrics["surplus"]: result = { **metrics, "action_taken": f"Surplus of {surplus_w}W available. Load optimization possible." } # Auto-trigger target if specified if target_load: load_map = { "heatpump": "switch.heatpump", "charger": "switch.ev_charger", "dishwasher": "switch.dishwasher", "washing": "switch.washing_machine" } entity_id = load_map.get(target_load.lower()) if entity_id: trigger_result = trigger_home_assistant(entity_id, "on") result["homeassistant"] = trigger_resultTechnical Analysis
...[truncated 2945 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse
HOME_ASSISTANT_URLwithurllib.parse.urlparseand reject malformed URLs. - Require
httpsfor authenticated requests. If a local installation cannot support TLS, explicitly restrict it to an approved private address and document the remaining interception risk. - Allowlist the exact expected Home Assistant hostname or IP address and permitted port instead of accepting an arbitrary destination.
- Reject URLs containing user information, query strings, fragments, or unexpected paths.
- Disable automatic redirects for authenticated requests, or independently validate every redirect destination before forwarding credentials.
- Use a dedicated, minimally privileged Home Assistant account and token limited to the entities and services required for load optimization.
- Store the token in an approved secret-management facility and rotate it immediately if exposure is suspected.
- Add
HOME_ASSISTANT_URLand the required secret toSKILL.md, clearly documenting why they are needed and that an authenticated network request is performed. - Consider requiring explicit confirmation or a configured power threshold before appliance activation, rather than activating a target whenever any negative total power is observed.
- Avoid returning raw exception text to callers where it could disclose internal endpoint or networking details; log sanitized diagnostic information separately.
- Parse
