Back to skill

Security audit

Voice Picker

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for SenseAudio voice selection, but its optional preview flow uses an unsafe shell command that can execute commands from preview text and sends text to SenseAudio without clear user confirmation.

Install only if you are comfortable with SenseAudio receiving preview text and an API key during audio generation. Until the preview command is rewritten with safe JSON construction and explicit confirmation, avoid using arbitrary or sensitive preview text and prefer using the recommendation-only part of the skill.

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

Error
Location
SKILL.md:121
Finding
Shell Command Injection Through Unsafely Interpolated TTS Preview Text<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 121–136 **Vulnerability Type**: Shell command injection caused by unsafe interpolation of user-controlled data **Risk Level**: High ### Vulnerable Code ```bash curl -s -X POST https://api.senseaudio.cn/v1/t2a_v2 \ -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"model\": \"SenseAudio-TTS-1.0\", \"text\": \"<PREVIEW_TEXT>\", \"stream\": false, \"voice_setting\": { \"voice_id\": \"<VOICE_ID>\" }, \"audio_setting\": { \"format\": \"mp3\" } }" -o preview.json jq -r '.data.audio' preview.json | xxd -r -p > preview_<VOICE_ID>.mp3 ``` ### Technical Analysis The Skill instructs the agent to substitute a user-supplied preview sentence directly into a double-quoted shell argument. Double quotes do not suppress command substitution in common shells: constructs such as `$(...)` and backticks are evaluated before `curl` executes. JSON escaping alone is insufficient because shell parsing occurs before the data is passed to `curl`. Consequently, preview text containing shell metacharacters can cause arbitrary commands to run locally. The output filename also interpolates `<VOICE_ID>` without shell-safe quoting. The documented workflow normally obtains this value from a fixed voice catalog, which limits practical exposure, but the implementation should still enforce an allowlist and quote the resulting path. ### Attack Path 1. An attacker asks the agent to generate a TTS preview. 2. The attacker supplies preview text containing command-substitution syntax, such as a sentence that embeds `$(id)`. 3. The agent follows the Skill and replaces `<PREVIEW_TEXT>` inside the provided shell command. 4. The shell evaluates the embedded command substitution before invoking `curl`. 5. The injected command executes with the same operating-system privileges and environment as the agent. 6. An attacker could extend this primitive to read acc ...[truncated 1007 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not construct JSON by interpolating user-controlled values into a shell command. Use `jq` or a programming-language JSON serializer to generate the request body as data: ```bash jq -n \ --arg text "$PREVIEW_TEXT" \ --arg voice "$VOICE_ID" \ '{ model: "SenseAudio-TTS-1.0", text: $text, stream: false, voice_setting: {voice_id: $voice}, audio_setting: {format: "mp3"} }' > request.json curl --fail-with-body -sS -X POST \ https://api.senseaudio.cn/v1/t2a_v2 \ -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @request.json \ -o preview.json ``` Apply the following additional controls: 1. Store preview text in a variable without evaluating it and always quote variable expansions. 2. Validate `VOICE_ID` against the exact voice IDs listed in the Skill rather than accepting arbitrary values. 3. Generate output paths in a controlled directory and use a fixed mapping from approved voice IDs to filenames. 4. Quote the output path, for example: ```bash output_file="previews/preview_${VOICE_ID}.mp3" jq -r '.data.audio' preview.json | xxd -r -p > "$output_file" ``` 5. Check the API response type and status before decoding it, and reject missing, malformed, or unexpectedly large audio fields. 6. Create temporary request and response files with restrictive permissions and unpredictable names, or avoid intermediate files entirely. 7. Prefer an HTTP client library over dynamically assembled shell commands when the execution environment supports one. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (4)

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The optional preview flow instructs the agent to send user-provided preview text to SenseAudio's external TTS API, but the skill does not require an explicit notice or consent step before transmitting that text. If a user includes sensitive or proprietary content in the sample sentence, it may be disclosed to a third party without clear warning.

External Transmission

Medium
Category
Data Exfiltration
Content
If the user wants to hear a sample, ask for a preview sentence (or use a default like "你好,欢迎体验 SenseAudio 语音服务。"), then call the TTS API:

```bash
curl -s -X POST https://api.senseaudio.cn/v1/t2a_v2 \
  -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
Confidence
90% confidence
Finding
The skill includes a curl command that transmits text and an API bearer token to an external service. External transmission is expected for TTS generation, but it still creates a real data-exposure boundary: user content leaves the local environment and is processed by a third party, which is risky if the text contains sensitive information or if users are unaware of the transfer.

External Transmission

Medium
Category
Data Exfiltration
Content
If the user wants to hear a sample, ask for a preview sentence (or use a default like "你好,欢迎体验 SenseAudio 语音服务。"), then call the TTS API:

```bash
curl -s -X POST https://api.senseaudio.cn/v1/t2a_v2 \
  -H "Authorization: Bearer $SENSEAUDIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
Confidence
90% confidence
Finding
The skill includes a curl command that transmits text and an API bearer token to an external service. External transmission is expected for TTS generation, but it still creates a real data-exposure boundary: user content leaves the local environment and is processed by a third party, which is risky if the text contains sensitive information or if users are unaware of the transfer.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The skill content, examples, voice labels, scenario guide, and sample text are presented almost entirely in Chinese, and the file does not state that the skill is region-specific or offer an alternative language/locale option. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Static analysis

No suspicious patterns detected.