Back to skill

Security audit

Feishu Voice Skill

Security checks for vulnerabilities and agentic risk

Overview

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.

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 (3)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:18
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 18 **Vulnerability Type**: Unpinned package installation and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```bash pip install edge-tts ``` ### Technical Analysis The installation instructions retrieve the current version of `edge-tts` and its transitive dependencies from the configured Python package index without specifying an audited version or verifying integrity hashes. Consequently, the code installed by users can change after this Skill has been reviewed. Although no malicious dependency is present in the audited project itself, package-index compromise, maintainer account compromise, or a malicious transitive dependency could introduce code that was not covered by this audit. Python packages may execute code during installation or when imported and invoked. ### Attack Path 1. An attacker compromises the `edge-tts` distribution, one of its dependencies, or the package index used by the victim. 2. The attacker publishes a malicious release that still satisfies the unrestricted installation command. 3. A user follows the documented instructions and runs `pip install edge-tts`. 4. The package manager retrieves and installs the attacker-controlled release. 5. Malicious package code executes during installation or when `edge-tts` is subsequently invoked by `feishu-voice-send.sh`. ### Impact Assessment Successful exploitation would execute code with the privileges of the user performing the installation or running the Skill. This could expose files, environment variables, and Feishu credentials accessible to that account, and could modify resources writable by that account. System-wide impact would be possible if the installation were performed with administrative privileges, although the documentation does not instruct users to do so. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Pin `edge-tts` and every transitive dependency to reviewed versions in a lock file. - Require package integrity verification through hashes, for example with `pip install --require-hashes -r requirements.txt`. - Install dependencies in a dedicated virtual environment rather than into the system Python environment. - Review and update pinned dependencies through a controlled process with automated vulnerability and provenance checks. - Avoid installing packages with administrative privileges. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
feishu-send.sh:39
Finding
Feishu Application Secret Exposed in Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `feishu-send.sh`, lines 39–42 **Vulnerability Type**: Sensitive credential exposure through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```bash 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'])") ``` ### Technical Analysis The shell expands `FEISHU_APP_ID` and `FEISHU_APP_SECRET` directly into curl's `-d` command-line argument. During curl execution, the resulting JSON body—including the application secret—may be visible through process inspection interfaces, process accounting, diagnostic tooling, audit logs, or monitoring agents. This undermines the documentation's claim that credentials are safely passed through environment variables: although they are initially supplied through the environment, the script copies them into a process argument. Exposure depends on the operating system's process-visibility controls, but it is avoidable and unnecessary for the declared messaging function. ### Attack Path 1. A user runs `feishu-send.sh` with valid Feishu credentials in the environment. 2. The script expands `FEISHU_APP_SECRET` into curl's argument vector. 3. A local user, privileged monitoring process, process-accounting facility, or diagnostic collector records or reads the curl command line while it is running. 4. The observer extracts the Feishu application ID and secret. 5. The observer submits those credentials to Feishu's tenant-access-token endpoint. 6. The resulting token can be used against Feishu APIs within the permissions granted to the associated application. ### Impact Assessment An attacker who obtains the application secret may impersonate the Feishu application and request tenant access tokens. The accessible d ...[truncated 254 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Construct the JSON request body without placing the secret in curl's argument vector. - Pass the body through standard input, for example by generating JSON with Python and using `curl --data-binary @-`. - Alternatively, write the body to a temporary file created with restrictive permissions and pass the filename to curl; securely delete it immediately afterward. - Ensure temporary files are created with `umask 077` or explicit owner-only permissions. - Avoid verbose shell tracing around credential-handling code and ensure CI logs do not record secrets. - Rotate the Feishu application secret if process logs or monitoring systems may already have captured it. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
feishu-voice-send.sh:46
Finding
Feishu Application Secret Exposed in Voice Sender Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `feishu-voice-send.sh`, lines 46–49 **Vulnerability Type**: Sensitive credential exposure through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```bash 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'])") ``` ### Technical Analysis The voice-sending script expands the Feishu application ID and secret into curl's command-line argument vector. The secret may therefore be exposed to process inspection, process accounting, system diagnostics, audit facilities, or monitoring software while the token request is running. Placing the secret in process arguments is not necessary to authenticate with Feishu. The request body can instead be transmitted through curl's standard input or a permission-restricted temporary file. ### Attack Path 1. A user invokes `feishu-voice-send.sh` with valid Feishu credentials. 2. The token request places the expanded application secret in curl's argument vector. 3. A local observer or process-monitoring facility captures the command line. 4. The observer recovers the application ID and application secret. 5. The observer requests a tenant access token from Feishu. 6. The observer invokes APIs authorized for the compromised Feishu application. ### Impact Assessment Credential compromise can allow unauthorized use of the Feishu application within its assigned API scope. Potential effects include unauthorized message delivery, file uploads, and access to any additional tenant operations granted to the application. The vulnerability does not itself escalate operating-system privileges; its scope is determined by local process visibility and the Feishu application's configured permissions. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Do not interpolate `FEISHU_APP_SECRET` into command-line arguments. - Generate the authentication JSON safely and pipe it into `curl --data-binary @-`. - If a temporary request file is used, create it in the existing private temporary directory with owner-only permissions and remove it immediately after use. - Disable shell command tracing while handling credentials and configure monitoring systems to redact Feishu secrets. - Apply the same credential-handling implementation consistently in both sender scripts. - Rotate potentially exposed application secrets and restrict the Feishu application to the minimum API permissions required for message and audio delivery. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明的核心能力是“通过 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 都不能为空,这与“支持纯语音发送”直接冲突。环境变量配置、无硬编码凭证这一点与声明一致,但不足以弥补主要能力描述不符。因此应判定为描述与实际代码行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
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.

External Script Fetching

High
Category
Supply Chain
Content
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'])")
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
[ -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'])")
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 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' \
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 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\\\"}\"}" \
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
91% confidence
Finding
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.

Vague Triggers

Medium
Confidence
95% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
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.

Intent-Code Divergence

Medium
Confidence
83% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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'])")
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
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'])")
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
| 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\\\"}\"}" \
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

Low
Confidence
84% confidence
Finding
L39-L45 仅列出“可用中文语音”,整体描述也围绕中文语音展开,但未明确说明这是面向中文场景的限定,也未提供语言/语音选择的用户 opt-in。按自然语言策略,这会形成默认语言/locale 限制。

Intent-Code Divergence

Low
Confidence
74% confidence
Finding
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.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
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.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
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.

Static analysis

No suspicious patterns detected.