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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

md
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'])")

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

md
| 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" \

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/send_voice_feishu.sh (reported line 81)May include surrounding context.

sh
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\"}")

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/send_voice_feishu.sh (reported line 82)May include surrounding context.

sh
# --- 获取 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',''))")

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/send_voice_feishu.sh (reported line 94)May include surrounding context.

sh
# --- 上传文件 ---
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)" \

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/send_voice_feishu.sh (reported line 108)May include surrounding context.

sh
# --- 发送语音消息 ---
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 "{

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
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.

Content

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

md
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'])")

External Transmission

Medium
Category
Data Exfiltration
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.

Content

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

md
| 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\\\"}\"}"

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send_voice_feishu.sh (reported line 82)May include surrounding context.

sh
# --- 获取 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',''))")

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/send_voice_feishu.sh (reported line 108)May include surrounding context.

sh
# --- 发送语音消息 ---
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 "{

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.