T07 · Tool Hijacking and Spoofing
- Location
scripts/speak.py:23- Finding
Arbitrary Python Module Execution Through a Shared Temporary Directory
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims, but it handles Xiaomi credentials and executable dependencies in ways users should review before installing.
Install only if you are comfortable giving the skill Xiaomi account credentials and remote control over linked speakers. Avoid storing MI_PASS in shell startup files, cron entries, or command strings; use a secret manager or a tightly permissioned local secret file instead. Do not import dependencies from /tmp/MiService; use a private virtual environment with pinned, verified dependency versions before running the skill.
scripts/speak.py:23Arbitrary Python Module Execution Through a Shared Temporary Directory
SKILL.md:32Xiaomi Account Password Stored in Plaintext Shell and Scheduled-Task Configuration
SKILL.md:203Unpinned and Unverified Executable Third-Party Dependencies
声明的核心用途是“让小爱说话”的播报/提醒类功能,但这段代码仅用于设备发现与枚举,是一个辅助脚本。它访问小米账号并调用设备列表接口,输出设备标识信息,却没有任何向音箱发送文本播报、创建提醒、远程喊话或家庭传话的实现。因此该代码块的实际主要行为与声明用途存在实质不一致,应判定为描述与行为不匹配。
代码的核心功能与“让小爱说话/语音播报”基本一致,但声明描述包含了额外能力:定时提醒、远程喊话、家庭传话。当前代码仅实现即时的文本转语音播报,没有看到任何定时任务、提醒创建、群发/家庭消息传递等逻辑。此外,声明权限为空,但代码实际依赖 MI_USER/MI_PASS 登录小米云,并读取设备列表后控制设备播报,涉及账号凭据和远程设备控制资源访问。因此描述对实际能力有夸大,且资源访问/权限声明不充分,属于描述与行为不完全匹配。
描述的核心“让小爱说话”与代码的主要功能基本相关,代码确实用于向小爱音箱发送播报消息。但代码实际还会读取小米账号和密码、调用外部脚本测试连接并列出设备,这些属于对外部账户和设备资源的访问,声明中未体现。更重要的是,声明强调“支持定时提醒、远程喊话、家庭传话”,而当前代码块只实现了 setup/test/list/say 这类命令行封装,定时仅在帮助示例里通过外部 cron 工具展示,未见内建的定时提醒、家庭传话或远程喊话逻辑。因此描述与实际行为存在一定偏差,尤其是在未声明的资源访问和夸大已实现能力方面。
The README explicitly tells users to append MI_USER and MI_PASS to ~/.zshrc, which stores Xiaomi account credentials in plaintext in a persistent shell startup file. This increases exposure to local compromise, accidental disclosure through backups/dotfile sync, shoulder-surfing, and inadvertent sharing, especially because these credentials grant access to Xiaomi account-linked devices and services.
The skill documentation clearly indicates use of environment variables, shell commands, and network access to Xiaomi cloud services, yet it declares no explicit tool scope or permissions. This weakens transparency and review controls, making it easier for a user or platform to underestimate the skill's ability to access credentials, invoke shell commands, and reach external services.
The instructions tell users to place Xiaomi credentials directly into shell commands and append them to ~/.zshrc, which can leave secrets exposed in shell history, dotfiles, backups, and local account compromise scenarios. Because these credentials enable access to cloud-connected devices, disclosure can lead to unauthorized device control and privacy loss.
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.
# 编辑 crontab
crontab -e
# 每小时提醒喝水
0 * * * * export MI_USER="xxx" MI_PASS="xxx" && /usr/bin/python3 /path/to/xiaoai-speaker/xiaoai_cli.py say "该喝水了"
The cron examples embed plaintext credentials directly in crontab entries and command strings, which may be readable by local users, administrators, backups, job inspection tools, or process listings. This creates a straightforward credential leakage path that can expose the user's Xiaomi account and associated smart-home devices.
This Python file contains natural-language descriptions and spoken output exclusively in Chinese, including the module docstring and all notification text. The skill does not offer any language selection or indicate that it is intentionally limited to a Chinese-speaking or region-specific context, which can violate language/locale policy requirements.
This Python file contains natural-language descriptions and user-facing reminder messages only in Chinese, but it does not indicate that the skill is region-specific or that the user can opt into this language. That can violate the language/locale policy because the skill effectively forces a specific language for all interactions.
This Python skill's natural-language descriptions, docstrings, and spoken messages are entirely in Chinese, indicating the skill is designed to operate in a single language without offering opt-in or alternatives. The policy explicitly flags language or locale constraints when they are imposed without user choice or justification.
The natural-language strings in the docstring, alert signal, and spoken message are all fixed in Chinese, and there is no indication that the user can opt into another language or configure locale. Under the language/locale policy, hard-coded language behavior without user choice or explicit justification is a policy concern.
The natural-language user-facing descriptions and usage guidance are entirely in Chinese, which may impose a language choice on users without offering an alternative or documenting that the skill is intended for a Chinese-only audience. Under the policy, forcing a specific language without user opt-in can be a locale/language policy violation.
This code file contains natural-language instructions and output messages that require Chinese comprehension, including setup and usage guidance. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified.
The module docstring and all user-facing messages are written in Chinese, and the script does not provide any option to select another language or indicate that it is intentionally limited to Chinese users. This is a natural-language locale policy issue because the skill enforces a specific language by default without user opt-in.
The script prepends '/tmp/MiService' to sys.path and then imports 'miservice' from that location, implicitly trusting code from a world-writable temporary directory. An attacker on the same system could place a malicious 'miservice' package there and achieve arbitrary code execution when the skill runs, including theft of the Xiaomi account credentials used by this script.
The say command invokes scripts/speak.py after requiring MI_USER and MI_PASS, which strongly implies a login-backed network action using Xiaomi account credentials. While missing credentials are reported, there is no user-facing disclosure here that the command will authenticate to an external service and transmit message content/account data.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 调用 speak.py
import subprocess
script_path = os.path.join(os.path.dirname(__file__), 'scripts', 'speak.py')
result = subprocess.run([sys.executable, script_path, message])
return result.returncode
def list_devices():
The list_devices command requires Xiaomi account credentials and launches scripts/list.py, indicating an external account/device query. The function reports missing environment variables but does not warn the user that it will access their account/device information over the network.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
import subprocess
script_path = os.path.join(os.path.dirname(__file__), 'scripts', 'list.py')
result = subprocess.run([sys.executable, script_path])
return result.returncode
def test():
The test command uses MI_USER and MI_PASS and runs scripts/list.py, which implies a real external authentication or account lookup rather than a local-only check. Although it prints that a connection test is happening, it does not disclose that account credentials will be used to contact Xiaomi services.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
import subprocess
script_path = os.path.join(os.path.dirname(__file__), 'scripts', 'list.py')
result = subprocess.run([sys.executable, script_path], capture_output=True, text=True)
if result.returncode == 0:
print("✅ 连接成功!")
The usage guidance says to avoid mixed English because pronunciation is inaccurate, which effectively imposes a language preference in the skill instructions. There is no accompanying opt-in or framing that this is only a quality recommendation based on current TTS limitations.
The module docstring is entirely in Chinese and presents the skill as its primary interface/description without indicating any language choice. This can violate a language/locale policy when users are not given an option to use another language or told that the skill is region- or language-specific.
This is a manifest file, so only markdown/plain-text style warnings are visible to the user here. The description states that MI_USER and MI_PASS environment variables are required, but it provides no user-facing warning about handling account credentials or privacy implications when configuring the skill.
No suspicious patterns detected.