T08 · Insecure Dependencies
- Location
SKILL.md:18- Finding
Unpinned Third-Party Dependency Installation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill does what it claims, but it handles Feishu app secrets unsafely enough that users should review it before installing.
Install only if you are comfortable sending the provided text/audio to Edge TTS and Feishu. Use a Feishu app with minimal permissions, avoid sensitive content, run it on a trusted machine, and consider fixing the curl secret handling before production use.
SKILL.md:18Unpinned Third-Party Dependency Installation
feishu-send.sh:39Feishu Application Secret Exposed in Process Arguments
feishu-voice-send.sh:46Feishu Application Secret Exposed in Voice Sender Process Arguments
声明的核心能力是“通过 Edge TTS 把文字转语音,发送到飞书”,并特别说明“支持纯语音发送和文字+语音同时发送”。但给出的代码片段实际只做了两件事:1)用 FEISHU_APP_ID/FEISHU_APP_SECRET 向飞书开放平台申请 tenant_access_token;2)发送文本消息后,再调用外部脚本 feishu-voice-send.sh 发送语音。该片段没有展示任何 Edge TTS、音频生成、文本转语音逻辑,因此其行为与声明的主要功能存在明显缺口。此外,脚本开头明确写着 Both text and voice are MANDATORY,并在参数校验中要求 TEXT 和 VOICE 都不能为空,这与“支持纯语音发送”直接冲突。环境变量配置、无硬编码凭证这一点与声明一致,但不足以弥补主要能力描述不符。因此应判定为描述与实际代码行为不匹配。
The core purpose mostly matches: the code performs text-to-speech with Edge TTS and sends the generated audio to Feishu using environment-based configuration and no hardcoded secrets. However, the description explicitly claims support for both pure audio sending and combined text+audio sending, while the code only sends an audio message (msg_type="audio") and contains no logic for sending a text message alongside it. Additionally, while 'no API Key' is technically plausible for Edge TTS, the skill still requires Feishu application credentials (FEISHU_APP_ID and FEISHU_APP_SECRET), so the description could mislead users into thinking no credentials are needed at all. Therefore this is a description-behavior mismatch, though the primary purpose is otherwise aligned.
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
fi
# Get token
TOKEN=$(curl -sf -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d "{\"app_id\":\"$FEISHU_APP_ID\",\"app_secret\":\"$FEISHU_APP_SECRET\"}" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tenant_access_token'])")
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
[ -z "$DURATION" ] && DURATION=1
# Step 4: Get tenant_access_token
TOKEN=$(curl -sf -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d "{\"app_id\":\"$FEISHU_APP_ID\",\"app_secret\":\"$FEISHU_APP_SECRET\"}" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tenant_access_token'])")
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
| python3 -c "import sys,json; print(json.load(sys.stdin)['tenant_access_token'])")
# Step 5: Upload opus
FILE_KEY=$(curl -sf -X POST 'https://open.feishu.cn/open-apis/im/v1/files' \
-H "Authorization: Bearer $TOKEN" \
-F 'file_type=opus' \
-F 'file_name=voice.opus' \
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['data']['file_key'] if d.get('code')==0 else f\"ERROR: {d.get('msg')}\")")
# Step 6: Send audio message
RESULT=$(curl -sf -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"receive_id\":\"$RECEIVE_ID\",\"msg_type\":\"audio\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}" \
The skill advertises executable workflows that use shell commands, environment variables, and network access, but it does not declare any tool scope or permissions boundaries. That creates a transparency and least-privilege problem: an agent or user may invoke a skill with broader capabilities than expected, including outbound transmission of message content and use of sensitive Feishu credentials.
Overly broad trigger phrases can cause accidental invocation of a skill that sends user-provided content to an external service. In this context, unintended activation is more dangerous because the skill uses network access and credentials to transmit messages to Feishu, potentially causing unapproved data disclosure or message spam.
The skill documentation omits a clear warning that text content and generated audio are sent to external services and that Feishu credentials are used to authenticate those transfers. Without explicit disclosure, users may unknowingly route sensitive information off-platform, making this a meaningful privacy and secret-handling risk in the context of messaging automation.
The comment at L05 states that both text and voice are mandatory with 'No exceptions.' In practice, the script sends the text message first at L45-L65 and only then invokes the separate voice-sending script at L68, so text may already be delivered even if the voice send fails or the helper script is missing.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
fi
# Get token
TOKEN=$(curl -sf -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d "{\"app_id\":\"$FEISHU_APP_ID\",\"app_secret\":\"$FEISHU_APP_SECRET\"}" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tenant_access_token'])")
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
fi
# Get token
TOKEN=$(curl -sf -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \
-H 'Content-Type: application/json' \
-d "{\"app_id\":\"$FEISHU_APP_ID\",\"app_secret\":\"$FEISHU_APP_SECRET\"}" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['tenant_access_token'])")
This shell script performs outbound HTTP requests to Feishu APIs to exchange credentials for a token and send user-provided text plus recipient metadata. While the code comments describe usage, they do not clearly warn the user that provided content and identifiers will be transmitted to an external service.
The script sends user-supplied text to the external edge-tts service to synthesize speech, but it provides no disclosure, consent prompt, or visible warning that the content leaves the local environment. This creates a privacy risk because sensitive prompts, secrets, or personal data could be transmitted to a third party unexpectedly in the normal course of using the skill.
The script uploads the generated audio, recipient identifier, and related metadata to Feishu APIs without any explicit runtime warning or confirmation. In an agent-skill context, this is more dangerous because a user may trigger it with sensitive content and unintentionally send that data to a third-party messaging platform or the wrong recipient.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['data']['file_key'] if d.get('code')==0 else f\"ERROR: {d.get('msg')}\")")
# Step 6: Send audio message
RESULT=$(curl -sf -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d "{\"receive_id\":\"$RECEIVE_ID\",\"msg_type\":\"audio\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}" \
L39-L45 仅列出“可用中文语音”,整体描述也围绕中文语音展开,但未明确说明这是面向中文场景的限定,也未提供语言/语音选择的用户 opt-in。按自然语言策略,这会形成默认语言/locale 限制。
The usage line documents a generic '[receive_id]' parameter, but the text send API call hardcodes 'receive_id_type=open_id' at L57 while the script also accepts FEISHU_CHAT_ID at L10 and L25-L26. This means the documented/accepted input can be a chat ID, yet the implementation still treats it as an open_id for the text message request.
The script's natural-language documentation mixes English with Chinese-only environment variable descriptions, which imposes a locale requirement on users reading the file. There is no indication that Chinese is optional or that an alternate language is offered for these instructions.
Several user-facing comments and error/help strings are provided only in Chinese, which constitutes a language constraint in the skill's natural-language interface. There is no indication that users can choose another language or that the locale restriction is intentionally scoped.