T08 · Insecure Dependencies
- Location
SKILL.md:18- Finding
Unpinned Third-Party Dependency Executes in the Credential-Handling Process
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a real Xiaomi smart-home controller, but it also handles powerful account credentials, polls lock events for occupancy-based automation, and ships household-specific identifiers with several under-scoped safety controls.
Review carefully before installing. Use only with a Xiaomi account and devices you control, pin and isolate the micloud dependency, avoid command-line passwords, rotate any password previously entered that way, protect or remove cached device and state files, and do not enable the lock-triggered fish-feeding cron unless you explicitly want occupancy-derived automation. Replace bundled home and device IDs with your own local configuration before use.
SKILL.md:18Unpinned Third-Party Dependency Executes in the Credential-Handling Process
scripts/mijia.py:62Xiaomi Password Is Exposed Through Echoed Input and Command-Line Arguments
scripts/mijia.py:91Sensitive Device Inventory Cache Is Created Without Restrictive Permissions
scripts/fish_auto_feed.py:40Occupancy-Related Automation State Is Stored Without Restrictive Permissions
references/devices.json:30Account-Specific Household Identifiers Are Embedded in the Distributed Project
The manifest describes an on-demand Xiaomi device control skill, but the documentation also includes unattended polling of door-lock history, leave-home inference, cron-based automation, and automated fish feeding. This hidden expansion from user-requested control to surveillance-like monitoring and autonomous actuation materially changes the trust model and can surprise users or operators.
This script implements autonomous behavior driven by lock telemetry rather than user-requested Xiaomi device control, which materially exceeds the declared skill purpose. In a smart-home skill, hidden automation tied to occupancy signals can create unexpected physical-world actions and erodes user consent and reviewability.
The skill documents shell execution, file reads, and file writes but declares no explicit tool scope or permissions boundary. That makes the agent’s effective authority ambiguous and increases the risk of overbroad execution, especially because the skill can access credential files, write state files, and issue device-control commands.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
description: |
Control Xiaomi Mi Home (米家) smart devices via Xiaomi Cloud API.
Use when: user wants to control smart home devices (lights, AC, heater, bath heater, switches, etc.),
check device status, or create automation scenes.
Triggers: "开灯", "关灯", "开空调", "关空调", "开浴霸", "我要洗澡", "设备状态",
"创建场景", "自动化", "米家", "smart home", "turn on/off", any home device control request.
NOT for: non-Xiaomi devices, HomeKit-only devices.
The trigger phrases are broad enough to match ordinary conversation, including generic terms like 'smart home', 'turn on/off', and 'any home device control request'. Overbroad activation can cause accidental invocation of shell-backed device actions, resulting in unintended changes to real-world devices or automations.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Prerequisites: pip3 install micloud
Credentials: ~/.mijia_creds.json (chmod 600)
{"userId":"...", "serviceToken":"...", "ssecurity":"...", "cUserId":"..."}
The documentation describes how to obtain and store long-lived Xiaomi session credentials, including service tokens and ssecurity values, without strong warnings about their sensitivity or handling controls. Exposure of these tokens could allow unauthorized access to the user’s Xiaomi cloud account and device fleet.
The fish-feeding workflow extends the skill from direct smart-home control into continuous polling of door-lock events and automated actuation based on inferred occupancy. This introduces privacy exposure and autonomous physical-world effects that are not obvious from the primary skill description.
The XiaoAI TTS feature adds a speaker-broadcast capability that is not declared in the manifest description or use cases. Undeclared audio output can be abused for spoofing, disruption, or privacy-invasive announcements, and users may not expect a device-control skill to speak aloud.
The registry exposes control metadata for a smart lock and router, which are materially more sensitive than ordinary lights or HVAC devices and exceed the skill’s narrowly described examples. In a home-control skill, including these identifiers increases the chance of unintended or unauthorized actions against security-critical infrastructure if prompt routing, name matching, or future tool logic is too permissive.
The scene metadata introduces a lock-event-driven fish-feeding automation that is outside the stated device-control scope and links a physical security event to an unrelated actuator. This kind of hidden cross-device automation expands behavior beyond user expectations and can create covert or unintended actions when the skill is used or extended.
The top-level documentation presents a successful once-per-day feeding flow, but the implementation explicitly saves last_feed_date regardless of API success and prints 'Will NOT retry today' on failure. That behavior contradicts the docstring's implied outcome because a failed run can still consume the day's feeding opportunity.
The script reads smart-lock event history to infer whether the user has left home, which is sensitive occupancy/behavioral data not obviously necessary for the stated purpose of direct device control. This broadens the skill from command execution into surveillance-like inference, increasing privacy risk and enabling unintended presence tracking.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
python3 mijia.py status <did> # Read device properties
python3 mijia.py set <did> <siid> <piid> <val> # Set a device property
python3 mijia.py get <did> <siid> <piid> # Get a device property
python3 mijia.py scene_create <json_file> # Create automation scene
python3 mijia.py scene_list # List automation scenes
python3 mijia.py batch <json_file> # Execute batch commands
The code forces zh_CN, GMT+08:00, and the cn server/region, which is a natural-language locale policy concern because it imposes a fixed language/locale context without opt-in. The file does not explain that this is a required region-specific tool or provide a configurable alternative.
The script reads the Xiaomi password using input(), which echoes the secret to the terminal and exposes it to shoulder surfing, screen recording, or captured terminal sessions. It also accepts --password on the command line, which can leak through shell history and process listings, making credential compromise more likely.
The manifest describes controlling Xiaomi smart home devices, checking status, and creating automation scenes, with examples like lights, AC, heaters, and switches. This function adds a separate capability to make a XiaoAI speaker speak arbitrary text, including volume/unmute/playback manipulation, which is not described in the manifest or trigger/use guidance.
The _doc string says device lookup is performed "by Chinese name," which imposes a Chinese-language naming convention. This is a natural-language locale constraint with no indication of user choice, opt-in, or justification in the file.
The default value for the scene name is the Chinese string "场景名称", which imposes a specific language in a natural-language field. Because the template does not indicate that this is optional, localized, or intended only for a Chinese-region deployment, it can violate language/locale policy expectations.
The script persists feeding state to a hidden file in the user's home directory via STATE_FILE.write_text(...), but there is no user confirmation around this write and the module docstring does not mention that local state will be stored. For a code file, file writes should have at least some visible disclosure through comments, logging, or documentation unless clearly warned elsewhere.