Back to skill

Security audit

小爱音箱语音播报

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/speak.py:23
Finding

Arbitrary Python Module Execution Through a Shared Temporary Directory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:32
Finding

Xiaomi Account Password Stored in Plaintext Shell and Scheduled-Task Configuration

Content
View full analysis
> ~/.zshrc echo 'export MI_PASS="你的小米密码"' >> ~/.zshrc source ~/.zshrc ``` ```bash # 编辑 crontab crontab -e # 每小时提醒喝水 0 * * * * export MI_USER="xxx" MI_PASS="xxx" && /usr/bin/python3 /path/to/xiaoai-speaker/xiaoai_cli.py say "该喝水了" # 每天8点早安 0 8 * * * export MI_USER="xxx" MI_PASS="xxx" && /usr/bin/python3 /path/to/xiaoai-speaker/xiaoai_cli.py say "早上好" ``` ```bash openclaw cron add \ --name "喝水提醒" \ --schedule "0 * * * *" \ --command "export MI_USER='xxx' MI_PASS='xxx' && python3 /path/to/xiaoai_cli.py say '该喝水了'" ``` ### Technical Analysis The setup instructions recommend writing the Xiaomi password directly into a shell startup file. The scheduling examples similarly embed credentials in crontab or OpenClaw task command strings. Environment variables avoid hardcoding secrets in application source code, but they do not provide secure storage when their values are permanently written to plaintext configuration. These files and task definitions may be copied into backups, exposed through diagnostics, read by other local software, or disclosed by permissive file permissions. The instructions also conflict with the Skill's assertion that account information is not stored in files. Shell initialization files and crontabs are persistent files. The cron functionality itself is related to the declared scheduled-reminder feature and is manually configured by the user. The project does not automatically register a scheduled task, so the reviewed behavior is not a covert system-persistence mechanism. The confirmed security issue is plaintext secret storage, not the existence of optional scheduling. ### Attack Path 1. A user follows the doc ...[truncated 972 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:203
Finding

Unpinned and Unverified Executable Third-Party Dependencies

Content
View full analysis
=3.8.0 ``` ```json "dependencies": { "python": ">=3.8", "pip": ["aiohttp"] } ``` ### Technical Analysis The documentation directs users to clone the mutable default branch of an external GitHub repository without identifying a reviewed tag or commit and without verifying a signature or cryptographic digest. The application subsequently imports executable Python code from that checkout. If the upstream repository, maintainer account, distribution path, or retrieved revision is compromised, malicious code can execute with access to Xiaomi credentials. Declaring the dependency to be inherently safe does not establish integrity. The `aiohttp` requirement is also only lower-bound constrained, while the package manifest supplies no version at all. This makes installations non-reproducible and permits future dependency versions to be selected without review. The reviewed project does not contain code that automatically performs the documented MiService clone. Therefore, the immediate remote-retrieval behavior is presented as manual installation guidance rather than an automatically triggered payload. The security weakness remains because users are instructed to retrieve and execute mutable upstream code. ### Attack Path 1. A user follows the documentation and clones the current default branch of `MiService`. 2. The retrieved revision contains a malicious or compromised update, or the local checkout is subsequently replaced. 3. The user runs a speaker or device-list command with `MI_USER` and `MI_PASS` available. 4. The Sk ...[truncated 770 chars]
Remediation
View remediation
=3.8.0` with a tested exact version or a tightly controlled compatible range, then use hash-verified installation. 6. Add an explicit installation script only if necessary, and make it fail closed when integrity verification fails. 7. Document the exact dependency source, revision, verification procedure, and update-review process. 8. Correct the claim that MiService is automatically installed, because no automatic bootstrap implementation exists in the reviewed code. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明的核心用途是“让小爱说话”的播报/提醒类功能,但这段代码仅用于设备发现与枚举,是一个辅助脚本。它访问小米账号并调用设备列表接口,输出设备标识信息,却没有任何向音箱发送文本播报、创建提醒、远程喊话或家庭传话的实现。因此该代码块的实际主要行为与声明用途存在实质不一致,应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

代码的核心功能与“让小爱说话/语音播报”基本一致,但声明描述包含了额外能力:定时提醒、远程喊话、家庭传话。当前代码仅实现即时的文本转语音播报,没有看到任何定时任务、提醒创建、群发/家庭消息传递等逻辑。此外,声明权限为空,但代码实际依赖 MI_USER/MI_PASS 登录小米云,并读取设备列表后控制设备播报,涉及账号凭据和远程设备控制资源访问。因此描述对实际能力有夸大,且资源访问/权限声明不充分,属于描述与行为不完全匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding

描述的核心“让小爱说话”与代码的主要功能基本相关,代码确实用于向小爱音箱发送播报消息。但代码实际还会读取小米账号和密码、调用外部脚本测试连接并列出设备,这些属于对外部账户和设备资源的访问,声明中未体现。更重要的是,声明强调“支持定时提醒、远程喊话、家庭传话”,而当前代码块只实现了 setup/test/list/say 这类命令行封装,定时仅在帮助示例里通过外部 cron 工具展示,未见内建的定时提醒、家庭传话或远程喊话逻辑。因此描述与实际行为存在一定偏差,尤其是在未声明的资源访问和夸大已实现能力方面。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% confidence
Finding

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.

Content

Scanner excerpt · SKILL.md (reported line 116)May include surrounding context.

bash
# 编辑 crontab
crontab -e

# 每小时提醒喝水
0 * * * * export MI_USER="xxx" MI_PASS="xxx" && /usr/bin/python3 /path/to/xiaoai-speaker/xiaoai_cli.py say "该喝水了"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · xiaoai_cli.py (reported line 85)May include surrounding context.

python
# 调用 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():

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · xiaoai_cli.py (reported line 98)May include surrounding context.

python
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():

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · xiaoai_cli.py (reported line 113)May include surrounding context.

python
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("✅ 连接成功!")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.