Back to skill

Security audit

smart-voice-reply

Security checks for vulnerabilities and agentic risk

Overview

This is a real voice-reply skill, but it needs Review because setup changes persistent agent behavior and the TTS tool sends user text to an external service while writing local files without tight scoping.

Install only if you are comfortable with your reply text and voice instructions being sent to DashScope and with local request/response files being written. Treat DASHSCOPE_API_KEY as a secret, review any USER.md changes before accepting them, and avoid enabling always-on voice replies unless you want persistent behavior. The temp-id handling should be fixed or avoided before use in shared or untrusted workflows.

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/tts_cli.js:195
Finding
Path Traversal and Arbitrary File Overwrite Through --temp-id## Vulnerability Details **File Location**: `scripts/tts_cli.js`, lines 89-96, 195-203, and 273-312 **Vulnerability Type**: Path traversal leading to writes outside the intended output directory **Risk Level**: Medium ### Vulnerable Code ```js return { text: values.text.trim(), voice, instructions: values.instructions ? values.instructions.trim() : undefined, optimizeInstructions: values["optimize-instructions"], outputDir: values["output-dir"].trim(), tempId: values["temp-id"] ? values["temp-id"].trim() : undefined }; ``` ```js function buildOutputPaths({ outputDir, tempId }) { const folderName = tempId ? `tmp-${tempId}` : `tmp-${Date.now()}`; const folderPath = path.resolve(outputDir, folderName); return { folderPath, sourcePath: path.join(folderPath, "source.mp3"), opusPath: path.join(folderPath, "audio.opus"), requestPath: path.join(folderPath, "request.json"), responsePath: path.join(folderPath, "response.json") }; } ``` ```js const paths = buildOutputPaths({ outputDir: args.outputDir, tempId: args.tempId }); await fsImpl.mkdir(paths.folderPath, { recursive: true }); await fsImpl.writeFile( paths.requestPath, JSON.stringify( { text: args.text, voice: args.voice, instructions: args.instructions }, null, 2 ), "utf8" ); await fsImpl.writeFile( paths.responsePath, JSON.stringify( { audio_url: ttsResult.audioUrl }, null, 2 ), "utf8" ); const audioBuffer = await downloadAudio({ audioUrl: ttsResult.audioUrl, fetchImpl, fsImpl }); await fsImpl.writeFile(paths.sourcePath, audioBuffer); ``` ### Technical Analysis The caller-controlled `--temp-id` value is trimmed but is not otherwise validated. It may therefore contain path separators and parent-directory components such as `../`. The code prefixes the ...[truncated 1989 chars]
Remediation
## Remediation Suggestions 1. Prefer removing the caller-controlled temporary directory name and generate it internally with `fs.mkdtemp()` or a cryptographically random identifier. 2. If `--temp-id` must remain supported, restrict it to a single safe path component, for example: ```js if (!/^[A-Za-z0-9_-]+$/.test(tempId)) { throw new CliError("Invalid temporary ID", { code: "INVALID_TEMP_ID" }); } ``` 3. Explicitly reject absolute paths, `/`, `\`, `.` and `..` path components. 4. Perform a containment check after resolution: ```js const base = path.resolve(outputDir); const folderPath = path.resolve(base, `tmp-${tempId}`); if (!folderPath.startsWith(base + path.sep)) { throw new CliError("Temporary path escapes output directory", { code: "INVALID_TEMP_PATH" }); } ``` 5. Resolve or canonicalize the output base and consider symlink-related boundary violations when the output directory may be controlled by another user. 6. Use exclusive file creation where overwriting is unnecessary, and apply restrictive directory and file permissions. 7. Add tests covering parent traversal, absolute paths, Windows separators, mixed separators, repeated traversal components, and symlink-based escape attempts.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared purpose understates the skill's real behavior: it uses an external API, writes files locally, and invokes additional processing tools, while also claiming voice creation/configuration that the description does not accurately constrain. This mismatch prevents informed consent and security review, and can lead to unexpected data exfiltration, local artifact creation, or unsafe execution paths when user text is sent to third-party services.

Ae1

High
Category
analysis-evasion
Content
scripts/tts_cli.js --text "<reply_text>" --voice <voice> --instructions "<instructions>" --output-dir <output_dir> [--optimize-instructions]
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill declares access to an environment secret (`DASHSCOPE_API_KEY`) but does not define explicit tool scope or permissions boundaries. That makes the capability surface implicit rather than auditable, increasing the risk that the skill can invoke sensitive functionality or be extended to do so without clear operator consent.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The invocation criteria are broad enough that the skill may trigger on loosely related requests about voice or replies, causing unintended execution of networked and message-sending actions. In a skill that can synthesize and send media, ambiguous routing increases the chance of surprise behavior, accidental disclosure, or misuse without a clear user request.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill instructs sending generated voice media to a user and explicitly suppresses a user-facing success message, reducing transparency around message transmission. This is dangerous because it can cause silent outbound communication and conceal that user content was transformed and sent as media, especially in environments where message delivery itself is sensitive.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The guide tells the agent to invoke another skill to create smart-voice-reply, which grants it agent-management behavior unrelated to simply providing voice replies. Chained self-installation or self-modification increases the risk of unauthorized capability expansion and makes the skill harder to review and contain.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The installation guide instructs persistent modification of the current agent's USER.md to auto-load the skill and always return voice responses. That changes the agent's long-term behavior beyond the narrow purpose of a voice-reply skill and can silently alter future interactions without clear user consent or scope limitation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The instructions direct editing USER.md, which is a persistent configuration surface, but they do not warn the user that this will permanently affect agent behavior. Silent or under-disclosed persistence is dangerous because users may think they are enabling a temporary voice feature when they are actually changing future default behavior.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guide requires setting DASHSCOPE_API_KEY but does not warn that it is a sensitive secret. This omission increases the chance that users will paste the key into insecure locations, logs, prompts, or version-controlled files, leading to credential leakage and downstream account abuse.

Natural-Language Policy Violations

Medium
Confidence
83% confidence
Finding
该文档在音色描述中直接规定“标准普通话,带部分北方口音”,属于自然语言层面的语言/locale 约束。文档未说明这是特定地区场景限定,也未向用户提供语言或口音上的选择,符合语言/locale policy violation 的判定条件。

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
在示例指令中,多处明确要求“以标准普通话”或“标准普通话发音”,但未提供其他语言、方言或口音选项,也未说明这是受业务边界限制的地区性工具。对所有用户默认施加单一语言/口音要求,属于可见的自然语言政策风险。

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Natural-language strings shown to users, including help text and validation errors, are written only in Chinese. This imposes a specific language on all users without offering a locale choice or documenting a justified region-specific constraint.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The CLI transmits user-provided text and optional instructions to a third-party cloud TTS service, but the interface gives no explicit notice that this content will leave the local environment. In a voice-reply skill, users may paste sensitive messages, prompts, or identifiers, so silent external transmission creates a real privacy and data-handling risk even though the behavior appears functionally intended.

Context-Inappropriate Capability

Low
Confidence
84% confidence
Finding
Requiring configuration of DASHSCOPE_API_KEY introduces credential and environment management instructions into end-user-facing skill documentation. While API keys may be necessary for functionality, embedding this in the skill guide without secure handling guidance can lead to unsafe secret exposure or misconfiguration.

Static analysis

No suspicious patterns detected.