Back to skill

Security audit

Feishu Voice (ElevenLabs)

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent Feishu voice-messaging purpose, but it needs review because it can send bot messages and route private audio/text through external services without strong opt-in or scoping controls.

Install only if you are comfortable with Feishu bot-send permissions and with voice/text content being sent to ElevenLabs. Use least-privileged Feishu app credentials, avoid shared hosts where process arguments may be visible, pin and verify the sag dependency, and require explicit user confirmation before enabling any smart or automatic reply flow.

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:12
Finding
Unpinned Global Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 12-13 **Vulnerability Type**: Unpinned and globally installed third-party dependency **Risk Level**: Medium ### Vulnerable Code ```markdown - `sag` CLI (ElevenLabs TTS): `npm i -g sag` or `go install` - `ffmpeg` / `ffprobe`: `brew install ffmpeg` ``` ### Technical Analysis The installation instructions direct users to install the latest available `sag` package globally without pinning a reviewed version or verifying package integrity. The alternative `go install` instruction also omits a module path and version. A global npm installation can run package lifecycle scripts with the privileges of the installing user. Because no version or integrity digest is specified, the code installed in the future may differ from the version reviewed with this Skill. This creates supply-chain exposure if the package registry account, package release process, or dependency tree is compromised. The audit did not establish that the current `sag` package is malicious. The risk arises from trusting mutable, unverified dependency content. ### Attack Path 1. An attacker compromises the package publisher, registry account, or a transitive dependency used by `sag`. 2. The attacker publishes a malicious package release under the expected package name. 3. A user follows the Skill instructions and runs `npm i -g sag`. 4. npm retrieves the latest mutable release and executes any applicable installation lifecycle scripts. 5. Malicious code executes under the installing user's account and the package remains globally available. ### Impact Assessment Successful exploitation could execute arbitrary code with the privileges of the user performing the installation. That code could access files, environment variables, API credentials, and network resources available to that user. Global installation also increases the persistence and scope of the compromised package relative to a project-local dependency. The inst ...[truncated 243 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Specify the exact, verified package source and publisher. - Pin `sag` to an audited version rather than installing the latest release. - Where supported, document and verify a package integrity digest or signed release artifact. - Prefer a project-local installation over `npm i -g` to reduce system-wide exposure. - Replace the incomplete `go install` instruction with a full module path pinned to an immutable version. - Document the dependency review and update process. - Advise users not to install dependencies with elevated privileges. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/feishu-voice-send.sh:48
Finding
Unsafe Construction of Feishu JSON and Query Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-voice-send.sh`, lines 48-67 **Vulnerability Type**: Improper encoding of JSON and URL query values **Risk Level**: Low ### Vulnerable Code ```bash # 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'])") # 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' \ -F "file=@$OPUS" \ -F "duration=$DURATION" \ | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['file_key'])") # Step 6: Send audio message RESULT=$(curl -sf -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=$RECEIVE_ID_TYPE" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d "{\"receive_id\":\"$RECEIVE_ID\",\"msg_type\":\"audio\",\"content\":\"{\\\"file_key\\\":\\\"$FILE_KEY\\\"}\"}") ``` ### Technical Analysis The script creates JSON through direct shell interpolation. Values such as `FEISHU_APP_ID`, `FEISHU_APP_SECRET`, and the command-line `RECEIVE_ID` are not JSON-escaped before being inserted into request bodies. Quotes, backslashes, or control characters in these values can terminate the intended JSON string, corrupt the payload, or introduce additional JSON properties. `RECEIVE_ID_TYPE` is also inserted directly into a URL query string without URL encoding or validation. Although the documentation describes only `open_id` and `chat_id` as valid values, the script does not enforce that allowlist. This is not shell command injection because the expansions occur inside quoted shell arguments. The practical risk is malformed or manipulated ...[truncated 1102 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Construct JSON with a serializer rather than shell string interpolation. For example, use `jq -n --arg` or Python's `json.dumps`. - Send generated JSON through standard input with `curl --data-binary @-`. - Restrict `RECEIVE_ID_TYPE` to an explicit allowlist containing only `open_id` and `chat_id`. - Use `curl --get --data-urlencode` or another proper URL encoder for query parameters. - Validate recipient identifiers against the expected Feishu identifier format before sending. - Keep all shell expansions quoted even after introducing structured encoding. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/feishu-voice-send.sh:48
Finding
Feishu Application Secret Exposed Through Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/feishu-voice-send.sh`, lines 48-51 **Vulnerability Type**: Sensitive credential exposed in a command-line argument **Risk Level**: Medium ### Vulnerable Code ```bash # 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'])") ``` ### Technical Analysis The Feishu application secret is expanded into the argument supplied to curl with `-d`. During execution, the resulting JSON body can therefore be present in curl's process argument list. Depending on operating-system process visibility, container isolation, monitoring configuration, and local user permissions, another process may be able to inspect this command line through facilities such as process listings or `/proc`. Shell quoting prevents command injection but does not prevent the expanded value from becoming part of curl's argument vector. ### Attack Path 1. A legitimate user invokes the voice-send script with `FEISHU_APP_SECRET` configured. 2. The script launches curl, placing the expanded application secret in its request-body argument. 3. A concurrent local process or user with sufficient process-inspection permission reads curl's argument list while the request is active. 4. The observer extracts the Feishu application ID and secret. 5. The observer uses the credentials to request a tenant access token. 6. The observer calls Feishu APIs within the application permissions and tenant controls assigned to that application. The observation window may be brief, but repeated script execution or process-monitoring tooling can make collection practical in a shared or compromised environment. ### Impact Assessment A captured application secret could allow an attacke ...[truncated 474 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Generate the authentication JSON with `jq` or Python and pipe it to curl through standard input: ```bash python3 -c 'import json, os; print(json.dumps({ "app_id": os.environ["FEISHU_APP_ID"], "app_secret": os.environ["FEISHU_APP_SECRET"] }))' | curl -sf -X POST \ 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \ -H 'Content-Type: application/json' \ --data-binary @- ``` - Avoid placing secrets in command-line arguments, URLs, logs, or diagnostic output. - Run the Skill under a dedicated account with restricted process visibility where feasible. - Grant the Feishu application only the permissions required to upload and send voice messages. - Rotate the application secret if process arguments may have been collected or logged. - Prefer a managed secret store or narrowly scoped environment injection over reading credentials from broad user configuration. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The supplied script accurately implements one subset of the description: sending a Feishu voice message using ElevenLabs-style TTS output and Feishu messaging APIs. However, the declared purpose also claims receiving Feishu audio messages, transcribing .ogg/.opus attachments with STT, and supporting smart reply logic that auto-replies differently based on message type. None of those behaviors appear in this code chunk. There is no inbound event handling, no STT/transcription, and no reply automation. This is therefore a description-to-code mismatch because the declared functionality is materially broader than the actual behavior shown.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a broader Feishu voice messaging skill with both STT and TTS plus smart reply behavior. The actual code is narrowly scoped to transcription of a supplied audio file via ElevenLabs STT. While STT is part of the declared functionality, the code chunk lacks the central Feishu integration and all reply/sending features described. This is a material description-behavior mismatch rather than a mere partial implementation detail.

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; print(json.load(sys.stdin)['data']['file_key'])")

# Step 6: Send audio message
RESULT=$(curl -sf -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=$RECEIVE_ID_TYPE" \
  -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.

External Script Fetching

High
Category
Supply Chain
Content
[ ! -f "$AUDIO_FILE" ] && echo "ERROR: File not found: $AUDIO_FILE" >&2 && exit 1

RESULT=$(curl -sf "https://api.elevenlabs.io/v1/speech-to-text" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -F "model_id=scribe_v1" \
  -F "file=@$AUDIO_FILE")
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 instructs use of shell commands and external scripts but does not declare any tool scope or allowed-tools restrictions. In an agent environment, this can cause overbroad execution capability, making it easier for the skill to access local files, invoke networked CLIs, or handle secrets without explicit approval boundaries.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill processes voice data and transcriptions through ElevenLabs, but the description does not clearly warn users that message content leaves the local/Feishu environment and is sent to a third party. This creates a privacy and compliance risk because users may unknowingly transmit sensitive audio, identities, or message content to an external processor.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill advertises a smart reply mode that may automatically send messages on the user's behalf, but it does not prominently warn about that behavior or require opt-in confirmation. In a messaging context, automatic outbound replies can cause unintended disclosures, impersonation-like effects, or reputational harm if triggered on sensitive conversations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This shell script sends the input text to ElevenLabs for TTS generation and posts Feishu credentials to obtain an access token, but it suppresses command output and provides no prompt, print statement, or explicit warning beyond terse usage comments. For a code file handling network transmission of user content and secrets, the absence of visible disclosure means users may not realize their data is being sent to third-party services.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The TTS invocation hard-codes '--lang zh', which imposes a specific language/locale regardless of user preference. The file does not offer opt-in language selection or explain why Chinese-only output is required, which matches the language/locale policy violation criteria.

External Transmission

Medium
Category
Data Exfiltration
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
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
| python3 -c "import sys,json; print(json.load(sys.stdin)['data']['file_key'])")

# Step 6: Send audio message
RESULT=$(curl -sf -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=$RECEIVE_ID_TYPE" \
  -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.

External Transmission

Medium
Category
Data Exfiltration
Content
[ ! -f "$AUDIO_FILE" ] && echo "ERROR: File not found: $AUDIO_FILE" >&2 && exit 1

RESULT=$(curl -sf "https://api.elevenlabs.io/v1/speech-to-text" \
  -H "xi-api-key: $ELEVENLABS_API_KEY" \
  -F "model_id=scribe_v1" \
  -F "file=@$AUDIO_FILE")
Confidence
97% confidence
Finding
This code sends local audio content to an external service endpoint, which is a genuine external data exfiltration path by design. In the context of voice-message handling, the transmitted content can include private conversations, secrets, or personal data, making the transfer security-relevant rather than a harmless network call.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script uploads the provided audio file to ElevenLabs' external speech-to-text API without any user-facing notice, consent check, or runtime warning. Because Feishu voice messages may contain sensitive or regulated content, this creates a real privacy and data-handling risk even if the transmission is functionally intended.

Static analysis

No suspicious patterns detected.