T09 · Insecure Skill Coding Practices
- Location
scripts/ecovacs.py:59- Finding
Reusable account credentials are stored without enforced access restrictions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill does what it says, but it handles Ecovacs account credentials and live robot-control commands with too little containment.
Review before installing. Use only with an account and machine you trust, because the helper can control a physical robot and stores reusable Ecovacs authentication material locally. Avoid putting real passwords or MD5 password values in shell history, delete or lock down `~/.ecovacs_session.json` after use, and prefer a revised version that prompts for credentials, stores only minimal tokens with 0600 permissions, validates command hostnames, and restricts commands to an allowlist with confirmation for persistent or disruptive actions.
scripts/ecovacs.py:59Reusable account credentials are stored without enforced access restrictions
scripts/ecovacs.py:97Bearer token can be transmitted to an insufficiently validated API-provided hostname
scripts/ecovacs.py:139Login credentials are accepted through command-line arguments
The skill performs network access to a cloud IoT API and writes session material to disk, but the manifest does not declare any permissions or allowed tool scope. That weakens least-privilege boundaries and makes it harder for a host or reviewer to understand and constrain what the skill can do, especially since it can issue live device-control actions.
The skill description emphasizes convenience features but does not clearly warn that it can send live commands to a physical robot and persist changes such as schedules or operational modes. In an agent setting, that omission increases the chance of accidental or insufficiently authorized actions affecting the physical environment.
The documentation states that token, userid, and resource are stored in ~/.ecovacs_session.json but does not warn about the sensitivity of that file or advise on protections. If the local environment is shared or compromised, an attacker could reuse the session material to control devices or query account-linked device information without needing the password again.
The documented cmd interface allows arbitrary command names and payloads to be sent to the robot API, going beyond the enumerated safe operations in the skill description. This expands the attack surface to undocumented or higher-risk device actions, including schedule changes or other state-altering commands, and bypasses intent-level validation.
The reference explicitly instructs clients to authenticate by sending a plaintext identifier and an MD5-hashed password to a remote service. MD5 is not suitable for password protection because it is fast and vulnerable to offline cracking if captured or logged, and documenting this flow without warnings or stronger compensating controls normalizes insecure credential handling. In the context of a robot-control skill, compromise could allow unauthorized control of physical devices and exposure of account-linked device metadata.
The script persists both the API token and the user's password hash in a predictable file under the home directory, with no permission hardening or warning to the user. Any local process or attacker with access to that file can reuse the token or stored password hash to control the user's robot account and devices, and the script itself uses the stored password to silently re-authenticate when the token expires.
The login request fixes the account context to country="CN" and org="ECOCN", and the device request also hard-codes language fields elsewhere. The file does not present this as an optional or justified region-specific behavior, so it imposes a locale/region choice without user opt-in.
The quick reference table switches to Chinese for operational descriptions and parameter meanings, while the rest of the document is primarily in English. This can impose a language constraint on users without opt-in or a documented locale justification, which matches the language/locale policy concern.