T09 · Insecure Skill Coding Practices
- Location
login_card.py:211- Finding
Hard-Coded Xiaomi OAuth Client Secret
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Xiaomi smart-home skill is not clearly malicious, but it asks for full Xiaomi login credentials and stores/handles tokens in ways that need careful review before use.
Review this skill carefully before installing. Only use it if you are comfortable entering Xiaomi account credentials into the assistant or Feishu card, having a bearer token cached locally, and exposing CAPTCHA/login artifacts through Feishu. Prefer a version that uses an official delegated login flow, enforces secure token storage, removes hardcoded secrets, and actually scopes access to the device-control operations you need.
login_card.py:211Hard-Coded Xiaomi OAuth Client Secret
miot_service.py:31Xiaomi Bearer Token Stored Without Enforced Access Permissions
login_card.py:181Predictable Shared CAPTCHA File Enables Symlink and Race Attacks
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
def get_tenant_token():
"""获取飞书 tenant token"""
resp = requests.post(
'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
json={'app_id': APP_ID, 'app_secret': APP_SECRET},
timeout=10
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
try:
password_hash = hashlib.md5(password.encode()).hexdigest().upper()
resp = requests.post(
"https://account.xiaomi.com/oauth2/token",
data={
"client_id": CLIENT_ID,
The skill is presented as an IoT control helper, but the behavior includes password login handling, challenge-response flow, persistent token caching, and device inventory retrieval. That broader account-access functionality materially changes the security posture because it can expose the user's Xiaomi account and all linked devices, not just execute a single device command.
The skill is presented as an IoT control helper, but the behavior includes password login handling, challenge-response flow, persistent token caching, and device inventory retrieval. That broader account-access functionality materially changes the security posture because it can expose the user's Xiaomi account and all linked devices, not just execute a single device command.
The login flow asks users to provide a Xiaomi phone number, password, and verification code in chat, yet the skill description does not prominently warn that highly sensitive credentials will be collected through the conversation. This creates a phishing-like pattern where users may disclose secrets without informed consent or understanding of how they are handled.
The skill explicitly instructs the assistant to solicit and process the user's Xiaomi account password and verification code in plain chat. In the context of a smart-home skill, this is especially dangerous because compromise of those credentials can grant broad account access, device inventory visibility, and control over connected home devices, while chat logs, intermediaries, or plugins may capture the secrets.
The code presents a Feishu card that asks the user to enter raw Xiaomi username and password directly into the skill. Collecting third-party account credentials inside a chat card is dangerous because it conditions users to disclose passwords to an intermediary service and gives the skill access to reusable credentials.
The skill transmits Xiaomi account credentials or password-derived material to external Xiaomi endpoints without any user-facing disclosure, consent language, or security notice in this file. In the context of a device-control skill, silent handling of raw credentials is especially dangerous because users may not understand that full account authentication is occurring.
The skill declares no explicit tool scope even though its documented behavior requires environment variable access, network communication, and local file storage for token caching. Without a permissions boundary, an agent platform may grant broader-than-expected capabilities, increasing the blast radius if the skill is misused or compromised.
The description says the skill should be used when the user says phrases like “开灯” and “关空调”. These are common smart-home utterances without clear scoping to Xiaomi/Mi Home context, which may cause unintended invocation when users make general requests rather than explicitly targeting this skill.
The file reads FEISHU_APP_ID and FEISHU_APP_SECRET from environment variables to authenticate outbound API calls, but there is no user-facing notice that the skill depends on and uses platform credentials. For safety auditing, access to sensitive credentials should be accompanied by visible disclosure or documentation unless clearly covered elsewhere.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def get_tenant_token():
"""获取飞书 tenant token"""
resp = requests.post(
'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
json={'app_id': APP_ID, 'app_secret': APP_SECRET},
timeout=10
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def get_tenant_token():
"""获取飞书 tenant token"""
resp = requests.post(
'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
json={'app_id': APP_ID, 'app_secret': APP_SECRET},
timeout=10
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def get_tenant_token():
"""获取飞书 tenant token"""
resp = requests.post(
'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
json={'app_id': APP_ID, 'app_secret': APP_SECRET},
timeout=10
The skill uploads a Xiaomi login captcha image to Feishu infrastructure. While not as severe as sending passwords, it still relays authentication-related material from one service into another platform, increasing exposure of the login process and potentially retaining artifacts outside the original trust boundary.
token = get_tenant_token()
with open(image_path, 'rb') as f:
resp = requests.post(
'https://open.feishu.cn/open-apis/im/v1/images',
headers={'Authorization': f'Bearer {token}'},
files={'image': ('captcha.png', f, 'image/png')},
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
def send_card(token, open_id, card):
"""发送卡片消息"""
resp = requests.post(
'https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id',
headers={
'Authorization': f'Bearer {token}',
The skill goes beyond the declared smart-home control purpose and implements Xiaomi account login plus account-wide device enumeration. That expansion of scope is risky because it enables collection of full account access and inventory data, which is materially more sensitive than issuing device-control commands.
This request retrieves the user's Xiaomi device inventory from Xiaomi's API after obtaining account access. In context, it expands access from simple device control to broad account data collection, which is more dangerous than the manifest suggests and increases the privacy impact if the skill is abused or compromised.
}
resp2 = session.get(
"https://api.io.mi.com/app/home/device/list",
headers=headers,
timeout=15
)
The skill requires the user's full Xiaomi account username and password and uses the OAuth password grant to obtain broad account access, which exceeds the narrow need implied by simple voice device control. In an agent-skill context, collecting primary credentials greatly increases blast radius if the skill, host, logs, or environment are compromised.
The manifest says the skill is used to control Xiaomi smart-home devices such as lights, air conditioners, and robot vacuums. In this file, the implemented behavior is limited to Xiaomi account authentication, token caching, captcha handling, and fetching/listing devices; there is no code that sends control commands to devices.
Credential-derived authentication material is sent to external services and the resulting bearer-like token ('macaroon') is cached locally without any protection controls or user warning. If the cache file is read by another local user, process, backup, or malware, it can enable unauthorized access to the user's Xiaomi account and devices.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
try:
password_hash = hashlib.md5(password.encode()).hexdigest().upper()
resp = requests.post(
"https://account.xiaomi.com/oauth2/token",
data={
"client_id": CLIENT_ID,
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"""用 macaroon token 获取设备列表"""
try:
resp = requests.get(
"https://api.io.mi.com/app/home/device/list",
headers={
"Authorization": f"Bearer {macaroon}",
"User-Agent": "Dalvik/2.1.0"
The manifest description and example invocation phrases are entirely in Chinese and imply a fixed interaction language. There is no indication that users may choose another language or that the Chinese-only behavior is a documented regional limitation.
Publishing a fixed client ID is less severe than exposing a client secret, but it still contradicts the surrounding claim about not hardcoding values and may encourage copy-paste reuse of a shared application identity. Shared identifiers can complicate auditing, rate limiting, and isolation between deployments.
No suspicious patterns detected.