Back to skill

Security audit

feishu-audio

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says: converts a local audio file and sends it as a Feishu voice message, with some operational risks users should understand.

Install only if you intend to send local audio files to Feishu through your own Feishu app credentials. Check the recipient OpenID before running it, avoid using sensitive audio on shared machines, and consider fixing the temporary-file handling before routine use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/send_audio.sh:38
Finding

Predictable Temporary File Permits Symlink Attacks and Cross-Run Interference

Content
View full analysis

Vulnerability Details

File Location: scripts/send_audio.sh, lines 38–41 and 107
Vulnerability Type: Predictable temporary file in a shared directory
Risk Level: Medium

Vulnerable Code

bash
# Temporary file
OPUS_FILE="/tmp/$(basename "$AUDIO_FILE" .mp3).opus"

echo "Converting audio to opus format..."
ffmpeg -i "$AUDIO_FILE" -c:a libopus -b:a 24k -ar 24000 -ac 1 -y "$OPUS_FILE" 2>/dev/null

The file is removed only after successful completion:

bash
rm -f "$OPUS_FILE"

Technical Analysis

The script constructs its output path deterministically from the source filename and stores it directly in the shared, world-writable /tmp directory. It does not use exclusive file creation, a private temporary directory, random path components, or checks that the destination is not a symbolic link.

Because ffmpeg is invoked with -y, it is instructed to overwrite the destination without confirmation. A local attacker who can predict the source basename may pre-create /tmp/<basename>.opus as a symbolic link to another file writable by the victim account. Depending on the destination and ffmpeg behavior, the target may then be overwritten with attacker-triggered audio output.

The predictable path also permits concurrent executions using the same basename to read, overwrite, upload, or delete one another's output. Furthermore, set -e may terminate the script before the final rm command, leaving converted audio behind in /tmp.

Attack Path

  1. The attacker determines or guesses the basename of an audio file likely to be processed, such as voice.mp3.
  2. The attacker creates the predictable path /tmp/voice.opus as a symbolic link to a file writable by the account that will run the Skill.
  3. The victim invokes the script with voice.mp3.
  4. The script runs ffmpeg with -y against the attacker-controlled path.
  5. ffmpeg may follow the symbolic link and overwrite the linked target with converted audio data. 6 ...[truncated 1058 chars]
Remediation
View remediation

Remediation Suggestions

Create a randomly named, private temporary directory and guarantee cleanup with an exit trap:

bash
TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/feishu-audio.XXXXXX")"
chmod 700 "$TMP_DIR"
trap 'rm -rf -- "$TMP_DIR"' EXIT HUP INT TERM

OPUS_FILE="$TMP_DIR/audio.opus"

ffmpeg -i "$AUDIO_FILE" \
    -c:a libopus \
    -b:a 24k \
    -ar 24000 \
    -ac 1 \
    -y \
    "$OPUS_FILE" 2>/dev/null

Additional hardening measures should include:

  1. Apply umask 077 before creating temporary content so files are accessible only to the current user.
  2. Keep the converted output inside the private directory rather than constructing a filename directly under /tmp.
  3. Retain the cleanup trap so temporary data is removed on success, errors, and common termination signals.
  4. Avoid relying on the input basename for uniqueness.
  5. Where practical, verify that the temporary output is a regular file owned by the current user before uploading it.
  6. Consider adding shell hardening such as set -euo pipefail, while explicitly validating required environment variables to avoid ambiguous failures.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill describes shell-based execution paths (bash scripts/send_audio.sh, ffmpeg, edge-tts) but does not declare any explicit tool scope or permissions. This creates an authorization and transparency gap: an agent may invoke shell capabilities without the skill clearly constraining what commands are expected, increasing the chance of unintended command execution or unsafe reuse in broader contexts.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The trigger phrases are broad and overlap with normal conversational language, such as requests for reading aloud or voice broadcast. In an agent environment, this can cause accidental activation of the skill, leading to unintended shell execution, audio generation, and sending messages to Feishu recipients without the user explicitly intending to invoke this workflow.

Content

No source excerpt is available for this finding.

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_audio.sh (reported line 52)May include surrounding context.

sh
# 获取 tenant_access_token
echo "获取飞书访问令牌..."
TOKEN_RESPONSE=$(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\"}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This shell script performs outbound HTTP requests to Feishu that transmit the user's audio file, authentication-derived access, and recipient metadata. Although it prints progress messages, those messages do not disclose the privacy-relevant fact that local content will be uploaded to an external service, and there is no confirmation prompt or descriptive warning comment/docstring covering that behavior.

Content

No source excerpt is available for this finding.

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_audio.sh (reported line 92)May include surrounding context.

sh
# 发送 audio 消息(duration 传秒)
echo "发送语音消息给: $RECEIVER (时长: ${DURATION}秒)"
MESSAGE_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"receive_id\": \"$RECEIVER\", \"msg_type\": \"audio\", \"content\": \"{\\\"file_key\\\": \\\"$FILE_TOKEN\\\", \\\"duration\\\": $DURATION}\"}")

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script's comments and all user-visible output are in Chinese, including usage, errors, and status messages. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy issue unless the locale constraint is explicitly justified or configurable.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.