Back to skill

Security audit

Qwen3-TTS + Feishu Voice

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated TTS and Feishu-sending purpose, but its Feishu helper script has unsafe filename handling that can execute attacker-controlled Python while Feishu credentials are available.

Review before installing. Use this only in a trusted workspace, patch the WAV filename handling in scripts/send_voice_feishu.sh before running it, pin dependencies where possible, and provide least-privilege Feishu app credentials only for the send operation. Do not synthesize or send sensitive text unless you are comfortable uploading the resulting audio to Feishu and delivering it to the configured recipient.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/send_voice_feishu.sh:51
Finding
Arbitrary Python Code Execution Through an Untrusted Audio Filename## Vulnerability Details **File Location**: `scripts/send_voice_feishu.sh`, lines 51–61 **Vulnerability Type**: Python source-code injection **Risk Level**: High **Vulnerable Code**: ```bash # 计算音频时长(毫秒),用于后续发送消息时传入 duration 字段 DURATION_MS=$(python3 -c " import wave, os try: with wave.open('$WAV_FILE') as f: frames = f.getnframes() rate = f.getframerate() print(int(frames / rate * 1000)) except Exception as e: print(0) ") ``` ### Technical Analysis `WAV_FILE` originates from the first command-line argument and is interpolated directly into source code passed to `python3 -c`. Shell quoting around the outer command does not make this safe because the expanded value becomes part of the Python program. A filename containing a single quote, Python delimiters, and additional statements can terminate the argument to `wave.open`, alter the generated Python program, and execute attacker-selected Python code. The preceding file-existence check only verifies that the supplied pathname exists; it does not validate or neutralize characters that are meaningful in Python source. The vulnerable duration calculation occurs after Feishu credentials have been loaded from `FEISHU_APP_ID` and `FEISHU_APP_SECRET`. Injected code therefore executes in a process environment that can access those credentials. ### Attack Path 1. An attacker creates or causes the user to receive a file whose pathname contains Python source-code metacharacters. 2. The attacker persuades the user or an automated workflow to invoke `send_voice_feishu.sh` with that pathname as the first argument. 3. The pathname passes the `[ -f "$WAV_FILE" ]` existence check. 4. The shell expands `$WAV_FILE` inside the program supplied to `python3 -c`. 5. The embedded quote terminates the intended Python string, and attacker-controlled statements become executable Python source. 6. Python executes those statements with the permissi ...[truncated 653 chars]
Remediation
## Remediation Suggestions Never interpolate a pathname into generated Python source. Pass it as a positional argument and read it through `sys.argv`: ```bash DURATION_MS=$(python3 -c ' import sys import wave try: with wave.open(sys.argv[1]) as audio: frames = audio.getnframes() rate = audio.getframerate() print(int(frames / rate * 1000)) except Exception: print(0) ' "$WAV_FILE") ``` Additional hardening should include: - Use `set -euo pipefail` and reference optional environment variables as `${FEISHU_APP_ID:-}` and `${FEISHU_APP_SECRET:-}`. - Treat all command-line pathnames as untrusted and pass them only as quoted data arguments. - Avoid constructing source code, JSON, or shell commands through string interpolation. - Add regression tests using filenames containing quotes, spaces, newlines, leading hyphens, and shell or Python metacharacters. - Run the Skill under an unprivileged account and provide Feishu credentials only for the duration of the send operation.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:30
Finding
Unpinned Third-Party Package Installation Creates Supply-Chain Risk## Vulnerability Details **File Location**: `SKILL.md`, lines 30 and 50 **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium **Vulnerable Code**: ```bash pip install qwen-tts soundfile modelscope ``` ```bash pip install huggingface_hub ``` ### Technical Analysis The installation instructions request package names without exact versions or cryptographic hashes. Consequently, the code installed by following the instructions depends on mutable package-index state and dependency resolution at installation time rather than on a reviewed, reproducible dependency set. A compromised package release, compromised maintainer account, malicious transitive dependency, or unexpectedly unsafe future version could be selected automatically. Third-party code may run during installation, when imported by `scripts/synthesize.py`, or when the documented download commands are invoked. The package names shown are consistent with the Skill's declared text-to-speech functionality, and the audit found no evidence that they are deliberate typosquatting packages. The issue is the absence of version and integrity controls, not a confirmed malicious dependency. ### Attack Path 1. An attacker compromises a required package, one of its transitive dependencies, or the package-distribution channel. 2. A malicious or vulnerable release becomes eligible for dependency resolution. 3. A user follows the documented unpinned `pip install` command. 4. `pip` retrieves the currently resolved release without verifying it against project-supplied hashes. 5. Malicious code executes during installation or when the installed package is subsequently imported or used. ### Impact Assessment A compromised dependency can execute with the privileges of the user performing installation or running the Skill. It could access local model and audio files, alter generated output, read user-accessible credentials, modify the virtual enviro ...[truncated 359 chars]
Remediation
## Remediation Suggestions - Pin every direct dependency to a reviewed exact version. - Resolve and lock all transitive dependencies using a reproducible lock file. - Generate and enforce cryptographic hashes, for example through a requirements file installed with `pip install --require-hashes -r requirements.txt`. - Configure an explicit trusted package index rather than relying on ambient `pip` configuration. - Review and update dependencies through a controlled process with vulnerability and provenance checks. - Retain the virtual-environment requirement and explicitly warn users not to install these packages with `sudo` or into a privileged system interpreter. - Pin the optional `huggingface_hub` dependency separately so the alternative model-download path is reproducible.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description emphasizes local TTS and 'no API key required,' but the instructions also include authenticated outbound Feishu API calls using app credentials. This mismatch can mislead users about data flow and trust boundaries, causing them to run a skill that transmits generated audio and uses secrets when they expected a purely local workflow.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description emphasizes local TTS and 'no API key required,' but the instructions also include authenticated outbound Feishu API calls using app credentials. This mismatch can mislead users about data flow and trust boundaries, causing them to run a skill that transmits generated audio and uses secrets when they expected a purely local workflow.

External Script Fetching

High
Category
Supply Chain
Content
ffmpeg -i output.wav -c:a libopus -b:a 24k output.opus -y

# 2. 获取 token
TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d '{"app_id":"YOUR_APP_ID","app_secret":"YOUR_APP_SECRET"}' \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['tenant_access_token'])")
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
| python3 -c "import json,sys; print(json.load(sys.stdin)['tenant_access_token'])")

# 3. 上传 opus 文件
FILE_KEY=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file_type=opus" \
  -F "file_name=audio.opus" \
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Credential Access

High
Category
Privilege Escalation
Content
echo "    ✓ $OPUS_FILE"

# --- 获取 Token ---
echo "2/4 获取 access token..."
TOKEN_RESP=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}")
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

External Script Fetching

High
Category
Supply Chain
Content
# --- 获取 Token ---
echo "2/4 获取 access token..."
TOKEN_RESP=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}")
TOKEN=$(echo "$TOKEN_RESP" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('tenant_access_token',''))")
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
# --- 上传文件 ---
echo "3/4 上传 opus 文件..."
UPLOAD_RESP=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file_type=opus" \
  -F "file_name=$(basename $OPUS_FILE)" \
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
# --- 发送语音消息 ---
echo "4/4 发送语音消息到 $TARGET_USER_ID..."
SEND_RESP=$(curl -s -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 "{
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill clearly instructs use of environment secrets and shell/network operations, but it does not declare an explicit tool scope such as permissions or allowed-tools. This creates an authorization and transparency gap: an agent or user may not realize the skill can access credentials and send network requests to Feishu, increasing the chance of unintended secret use or outbound actions.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill instructs users to upload generated audio to Feishu and send it to a recipient, but it does not provide an explicit privacy or data-sharing warning. Users may assume the workflow remains local because much of the document stresses local synthesis, when in fact the audio content and associated metadata are transmitted to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
ffmpeg -i output.wav -c:a libopus -b:a 24k output.opus -y

# 2. 获取 token
TOKEN=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d '{"app_id":"YOUR_APP_ID","app_secret":"YOUR_APP_SECRET"}' \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['tenant_access_token'])")
Confidence
90% confidence
Finding
This command sends FEISHU_APP_ID and FEISHU_APP_SECRET to Feishu to obtain a tenant access token, which is an outbound transmission of sensitive credentials. Even though this is expected for the API flow, it is still security-relevant because it relies on secret handling and network trust, and should be clearly disclosed and scoped.

External Transmission

Medium
Category
Data Exfiltration
Content
| python3 -c "import json,sys; print(json.load(sys.stdin)['data']['file_key'])")

# 4. 发送语音气泡
curl -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\":\"TARGET_OPEN_ID\",\"msg_type\":\"audio\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}"
Confidence
94% confidence
Finding
This command transmits a message request to Feishu using a bearer token and causes externally visible communication to a target recipient. In context, it also depends on a previously uploaded audio file, so the skill is not purely local and can disclose generated content to third parties if used carelessly.

External Transmission

Medium
Category
Data Exfiltration
Content
# --- 获取 Token ---
echo "2/4 获取 access token..."
TOKEN_RESP=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
  -H "Content-Type: application/json" \
  -d "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}")
TOKEN=$(echo "$TOKEN_RESP" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('tenant_access_token',''))")
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# --- 发送语音消息 ---
echo "4/4 发送语音消息到 $TARGET_USER_ID..."
SEND_RESP=$(curl -s -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 "{
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
The module docstring and runtime messages are written in Chinese only, including usage instructions and warnings. Because the script does not offer a language/locale choice for its interface text, it effectively forces a specific language on users.

Natural-Language Policy Violations

Medium
Confidence
89% confidence
Finding
The function signature hard-codes `language="Chinese"` as the default, and the CLI path also falls back to `"Chinese"` when no language is provided. This imposes a specific language choice by default rather than offering a neutral default or explicit user selection, which is a natural-language locale policy concern.

Static analysis

No suspicious patterns detected.