Back to skill

Security audit

Feishu Voice Bubble

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward Feishu voice-message helper, but users should treat generated speech text as data sent to Microsoft Edge TTS and be careful with npm dependency installation and output paths.

Before installing, confirm you are comfortable sending the text to Microsoft Edge TTS, avoid sensitive or regulated content unless approved, pin and review the npm dependency, and keep generated audio paths inside a dedicated output directory.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:23
Finding
Unpinned Third-Party TTS Dependency Creates Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:23-28` **Vulnerability Type**: Unpinned third-party dependency **Risk Level**: Medium ### Vulnerable Code ```markdown ## Prerequisites ```bash npm install node-edge-tts ``` ``` ### Technical Analysis The documented installation command retrieves the latest version of `node-edge-tts` rather than a specific, reviewed version. The project contains no package manifest, lockfile, integrity hash, or other mechanism that ensures users install a known dependency artifact. An npm installation can also execute package lifecycle scripts. Consequently, the effective code installed and potentially executed by users may change after this Skill has been reviewed. This creates exposure to package-account compromise, malicious future releases, registry compromise, or unexpected upstream changes. The audit did not find evidence that `node-edge-tts` is currently malicious. The vulnerability is the absence of dependency pinning and integrity controls. ### Attack Path 1. An attacker compromises the upstream package, its maintainer account, or its distribution process and publishes a malicious release. 2. A user follows the Skill's documented `npm install node-edge-tts` command. 3. npm resolves the unpinned dependency to the malicious or compromised release. 4. Malicious code may run through an npm lifecycle script during installation or when `gen_voice.js` imports and invokes the package. 5. The code executes with the permissions of the user or Agent running npm or the Skill. ### Impact Assessment Successful exploitation could permit arbitrary code execution under the installing or invoking user's account. Depending on that account's privileges, the attacker could access local files, environment variables, Agent-accessible credentials, and network resources, or modify other writable project files. The scope is limited by the operating-system permissions and sandbox restrictions applied to npm and Node.js. ...[truncated 75 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a `package.json` that pins `node-edge-tts` to an exact, reviewed version rather than using a floating version range. 2. Commit a generated lockfile containing dependency versions and registry integrity hashes. 3. Replace the documented installation command with `npm ci` so installation follows the lockfile exactly. 4. Review the dependency's source, transitive dependencies, maintainers, and lifecycle scripts before approving upgrades. 5. Use automated dependency scanning and update only through reviewed changes. 6. Where compatible with the package, install dependencies with lifecycle scripts disabled, such as `npm ci --ignore-scripts`. 7. Run installation and TTS generation in a sandbox with minimal filesystem, credential, and network access. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gen_voice.js:112
Finding
Caller-Controlled Output Path Allows Unrestricted File Creation or Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/gen_voice.js:112-144` **Vulnerability Type**: Unrestricted filesystem output path **Risk Level**: Medium ### Vulnerable Code ```javascript const outputPath = path.resolve(args.outputPath); if (!outputPath.endsWith('.opus')) { console.error('Warning: output path should end with .opus for Feishu voice bubble support'); } const chunks = splitText(args.text, args.split); if (chunks.length === 1) { // Single file const size = await generateOne(chunks[0], outputPath, args.voice, args.rate, args.pitch); console.log(JSON.stringify({ status: 'ok', path: outputPath, voice: args.voice, rate: args.rate, size, textLength: args.text.length, chunks: 1, })); } else { // Multiple files: output_1.opus, output_2.opus, ... const ext = path.extname(outputPath); const base = outputPath.slice(0, -ext.length); const files = []; for (let i = 0; i < chunks.length; i++) { const filePath = `${base}_${i + 1}${ext}`; const size = await generateOne(chunks[i], filePath, args.voice, args.rate, args.pitch); files.push({ path: filePath, size, textLength: chunks[i].length }); } ``` The resulting path is passed to the dependency at `scripts/gen_voice.js:97`: ```javascript await tts.ttsPromise(text, outputPath, opts); ``` ### Technical Analysis The second positional argument is accepted as an output path and normalized with `path.resolve()`, but it is not restricted to an approved output directory. Absolute paths and relative paths containing traversal components are therefore accepted. The script does not reject an existing destination, does not enforce an `.opus` extension, and does not establish exclusive-create semantics. The extension check only prints a warning. In split mode, additional filenames are derived from the same untrusted base path. The final write operation occurs inside `node-edge-tts`, so ...[truncated 1639 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated output directory and resolve every destination relative to that directory. 2. Compare the canonical destination against the canonical output-directory path and reject destinations outside it. 3. Accept only a safe filename from the caller rather than an arbitrary path. 4. Enforce the `.opus` extension instead of merely issuing a warning. 5. Reject existing output files by default and require explicit authorization before overwriting. 6. Use exclusive file creation where supported to reduce overwrite and race-condition risks. 7. Validate all split-file destinations individually before generation. 8. Consider rejecting symbolic-link destinations and checking canonical parent paths immediately before writing. 9. Run the script with minimal filesystem permissions and expose only the dedicated output directory to the process. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill claims end-to-end Feishu voice-bubble delivery, but the documented behavior only covers local audio generation and relies on an implied external plugin behavior to actually send messages. This mismatch is dangerous because users may assume the skill has Feishu-native sending guarantees, permission boundaries, and message-delivery behavior that are not actually implemented or documented, leading to misuse, failed controls, or unsafe automation assumptions.

Ae1

High
Category
analysis-evasion
Content
node scripts/gen_voice.js "你好世界" output.opus
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/gen_voice.js "你好世界" output.opus
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node scripts/gen_voice.js "你好世界" output.opus
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill prominently advertises free Edge TTS usage but does not clearly warn up front that message text is sent to a Microsoft-hosted external service for synthesis. This is a meaningful privacy and data-handling issue because users may provide sensitive or regulated content under the assumption processing is local or confined to Feishu.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The invocation guidance uses broad trigger phrases such as requests for voice messages or audio replies without clearly constraining when the skill should activate. Overbroad triggers can cause accidental invocation on unrelated chat content, increasing the chance that sensitive text is converted and transmitted to an external TTS service without sufficiently explicit user intent.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script sends arbitrary input text to Microsoft's Edge TTS service via a network request, but the CLI/help text only says 'No API key required' and does not clearly warn users that message content leaves the local environment. In a Feishu messaging skill, users may provide chat content, internal notes, or personal data expecting local conversion, so this creates a real privacy and data-handling risk even though it is not an exploit primitive like code execution.

Static analysis

No suspicious patterns detected.