Back to skill

Security audit

speech-translation

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent voice-translation pipeline, but its optional notifier hooks can execute arbitrary shell commands on the user’s machine.

Review before installing. Use the core pipeline only with trusted audio and trusted output paths. Do not enable transcript, translation, or audio command hooks unless you wrote and trust the exact command, because those hooks can run arbitrary shell commands and receive potentially sensitive spoken content. Prefer local LLM/Piper paths for private content, avoid unaudited HTTP translation services, and install dependencies in an isolated pinned environment.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/voice_translate_app/notifier.py:47
Finding
Shell Command Injection Through Notification Hooks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/voice_translate_app/notifier.py:47-59` **Additional Locations**: `scripts/voice_translate_app/cli.py:42-44, 67-69`; `scripts/send_text.py:25-26, 54`; `scripts/send_audio.py:15-16, 38-44` **Vulnerability Type**: OS command injection through unsafe shell invocation **Risk Level**: High ### Vulnerable Code ```python def _run_text_command(self, command: str | None, text: str) -> None: if not command: return subprocess.run(command, input=text.encode("utf-8"), shell=True, check=True) def _run_audio_command(self, command: str | None, audio_file: Path) -> None: if not command: return if "{audio_file}" in command: resolved = command.format(audio_file=str(audio_file)) else: resolved = f'{command} "{audio_file}"' subprocess.run(resolved, shell=True, check=True) ``` Related standalone wrapper: ```python command = args.command_template.format(audio_file=shlex.quote(str(audio_path))) if args.dry_run: print(command) return subprocess.run(command, shell=True, check=True) ``` ### Technical Analysis Notification commands are accepted from command-line arguments or environment-backed command templates and passed to `subprocess.run` with `shell=True`. This causes the system shell to interpret command separators, substitutions, redirections, pipelines, and other metacharacters. The audio notifier introduces an additional injection boundary by interpolating `audio_file` directly into the shell command. In the placeholder branch, the path is inserted without any quoting. In the fallback branch, it is enclosed in double quotes but embedded quote characters are not escaped. Because the generated audio path includes the operator-provided output directory, an attacker who can influence that directory can potentially insert shell syntax into the resulting command. The standalone sender uses `shlex.quote` for the audio path, which protects that specif ...[truncated 1729 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `shell=True` and execute commands using argument arrays: ```python import shlex import subprocess argv = shlex.split(command) subprocess.run(argv, input=text.encode("utf-8"), check=True) ``` 2. For audio notifications, append the path as a separate argument rather than interpolating it into a command string: ```python argv = shlex.split(command) argv.append(str(audio_file)) subprocess.run(argv, check=True) ``` 3. Replace free-form shell templates with a structured configuration containing an executable and argument list. 4. If placeholder support is required, substitute placeholders at the argument level after parsing, not in a complete shell string. 5. Validate configured executables against an allowlist or require absolute executable paths in security-sensitive deployments. 6. Treat notifier configuration and related environment variables as privileged configuration. Do not populate them from chat content, transcript content, attachment metadata, or other untrusted input. 7. Add regression tests using paths containing spaces, quotes, semicolons, command substitutions, and newline characters to verify that they remain literal arguments. 8. Run the pipeline under a dedicated, minimally privileged operating-system account and restrict its filesystem and network access. ]]>

T08 · Insecure Dependencies

Warning
Location
references/runtime-notes.md:34
Finding
Unpinned Third-Party Runtime Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `references/runtime-notes.md:34-46` **Vulnerability Type**: Unpinned dependency installation and non-reproducible supply chain **Risk Level**: Medium ### Vulnerable Code ```markdown Typical real run dependencies: - Python 3.10+ - `faster-whisper` - `requests` - `piper` binary available on PATH, or pass `--piper-binary` - a Piper `.onnx` voice model and matching `.onnx.json` Install Python deps with: ```bash pip install faster-whisper requests ``` ``` ### Technical Analysis The documented installation command does not constrain dependency versions or verify package hashes. Each installation can therefore resolve different versions of `faster-whisper`, `requests`, and their transitive dependencies. This makes the runtime non-reproducible and exposes users to future compromised releases, malicious transitive dependencies, unexpected breaking changes, or unsafe packages supplied through a misconfigured package index. No evidence was found that the named packages are intentionally malicious; the weakness is the absence of version and integrity controls. ### Attack Path 1. A user follows the documented `pip install faster-whisper requests` command. 2. pip queries the configured package index and resolves the versions available at installation time. 3. A direct or transitive package has been compromised, replaced, or unexpectedly changed, or the environment uses an attacker-controlled index. 4. pip downloads and installs that package without project-defined version or hash verification. 5. Malicious installation or runtime code executes with the privileges of the user performing the installation or running the pipeline. ### Impact Assessment A successful supply-chain compromise could execute arbitrary code during installation or application startup. The resulting access would generally match the privileges of the installation or runtime account and could include: - Reading project files, transcripts, ...[truncated 386 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a reviewed lock file or requirements file with exact versions for direct and transitive dependencies. 2. Require package hashes, for example through a generated requirements file used with: ```bash pip install --require-hashes -r requirements.txt ``` 3. Document the expected package index and avoid untrusted or implicit extra indexes. 4. Install dependencies in an isolated virtual environment rather than into a global Python environment. 5. Add automated dependency vulnerability and integrity scanning to the release process. 6. Review and deliberately update locked dependencies on a controlled schedule. 7. Pin and verify the Piper distribution and voice-model sources as well, including checksums or signatures where available. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (40)

Tainted flow: 'message' from sys.stdin.read (line 43, user input) → subprocess.run (code execution)

Critical
Category
Data Flow
Content
"No command template provided. Use --command-template or set VOICE_TRANSLATE_TEXT_COMMAND_TEMPLATE."
        )

    subprocess.run(args.command_template, input=message.encode("utf-8"), shell=True, check=True)


if __name__ == "__main__":
Confidence
90% confidence
Finding
External input (network, user) flows to a code execution sink. This enables remote code execution or command injection.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented workflow includes sending transcript text to an external translation service over HTTP and using manual fallback flows not reflected in the declared purpose. In a speech-translation context, transcripts commonly contain sensitive spoken content, so undocumented external transmission and mismatched behavior increase the risk of unintended data exposure and unsafe deployment assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The documented workflow includes sending transcript text to an external translation service over HTTP and using manual fallback flows not reflected in the declared purpose. In a speech-translation context, transcripts commonly contain sensitive spoken content, so undocumented external transmission and mismatched behavior increase the risk of unintended data exposure and unsafe deployment assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The documented workflow includes sending transcript text to an external translation service over HTTP and using manual fallback flows not reflected in the declared purpose. In a speech-translation context, transcripts commonly contain sensitive spoken content, so undocumented external transmission and mismatched behavior increase the risk of unintended data exposure and unsafe deployment assumptions.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented workflow includes sending transcript text to an external translation service over HTTP and using manual fallback flows not reflected in the declared purpose. In a speech-translation context, transcripts commonly contain sensitive spoken content, so undocumented external transmission and mismatched behavior increase the risk of unintended data exposure and unsafe deployment assumptions.

Ae1

High
Category
analysis-evasion
Content
- Keep `SKILL.md` procedural and short.
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Tool Parameter Abuse

High
Category
Tool Misuse
Content
print(command)
        return

    subprocess.run(command, shell=True, check=True)


if __name__ == "__main__":
Confidence
97% confidence
Finding
This is a classic tool-parameter abuse issue: the executable behavior is delegated to a caller-controlled template and then run through the shell. In an agent skill context, this is more dangerous because automation, environment-variable configuration, or upstream user influence can turn a simple audio handoff into arbitrary local command execution, potentially exposing files, secrets, or enabling lateral actions.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
resolved = command.format(audio_file=str(audio_file))
        else:
            resolved = f'{command} "{audio_file}"'
        subprocess.run(resolved, shell=True, check=True)

    def notify_transcript(self, text: str) -> None:
        self._run_text_command(self.transcript_command, text)
Confidence
99% confidence
Finding
This is a strong example of tool parameter abuse: a configurable command template directly controls a shell invocation and interpolates the audio_file parameter into it. In a skill that processes externally supplied audio and may operate automatically, this is especially dangerous because normal workflow inputs can become a trigger for arbitrary OS command execution without additional trust checks.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and instructs use of shell, file, environment, and network-capable operations but declares no explicit tool scope or permission boundaries. In an agent setting, this increases the chance that the skill can invoke high-risk capabilities without least-privilege constraints, enabling unintended command execution, filesystem modification, or outbound data transfer.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill documents sending transcript text to a translation service endpoint without any warning that spoken content may be transmitted off-host. Because transcripts may contain private conversations, credentials, business data, or regulated information, silent HTTP forwarding can cause confidentiality breaches and compliance issues, especially if users assume the workflow is local.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This markdown file instructs the agent to transcribe inbound voice messages, translate them, and send translated audio, which are operations that affect user data and privacy. The description does not include any warning or disclosure that voice content will be processed, transformed, and returned through tools.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The transcript and translation templates hard-code Chinese headings ("转写结果" and "翻译结果") for user-visible output. This imposes a specific language on users without opt-in or justification, which is a natural-language locale policy concern.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The notes define an external HTTP translation service contract but do not clearly warn that transcript content—potentially sensitive spoken data—will be transmitted off-host to a network service. In a speech-translation skill, transcripts commonly contain private conversations or personal data, so omitting this disclosure increases the risk of unintentional data exfiltration and insecure deployment choices.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
This helper script is meant to send audio onward, but it does so by executing an arbitrary command template supplied via CLI or environment variable. That creates a generic command-execution surface not constrained to audio translation, so any process that can influence configuration can repurpose the skill to run unrelated system commands.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print(command)
        return

    subprocess.run(command, shell=True, check=True)


if __name__ == "__main__":
Confidence
96% confidence
Finding
The script builds a shell command from a user/environment-controlled template and executes it with shell=True. Even though the audio_file value is shell-quoted, the template itself is arbitrary and can include additional shell metacharacters or unrelated commands, enabling command injection or execution of attacker-chosen programs.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code executes a shell command built from a user- or environment-supplied template via subprocess.run(..., shell=True). Although a dry-run mode exists, the normal execution path provides no confirmation prompt, no logging/print of the command being executed, and no inline warning comment or docstring disclosing that the script will invoke an external command to transmit the audio file.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"No command template provided. Use --command-template or set VOICE_TRANSLATE_TEXT_COMMAND_TEMPLATE."
        )

    subprocess.run(args.command_template, input=message.encode("utf-8"), shell=True, check=True)


if __name__ == "__main__":
Confidence
97% confidence
Finding
The script executes a caller-controlled command template with shell=True, allowing shell metacharacters, command chaining, and environment expansion to be interpreted by the shell. In this skill context, the command can be supplied from a CLI argument or environment variable, so a malicious or misconfigured workflow can trigger arbitrary command execution on the host running the agent.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script forwards transcript/translation content to an external command without a clear runtime consent or warning boundary, which can leak sensitive spoken content to other processes or external services. In a speech-translation skill, inputs commonly contain private audio-derived text, making silent transmission more risky than in a generic utility.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The CLI exposes user-configurable command hooks for transcript, translation, and audio post-processing, which expands the tool from speech translation into arbitrary command execution. In an agent skill context, these options are especially dangerous because untrusted inputs or workflow configuration could cause execution of attacker-chosen local programs, leading to command injection or abuse of the host environment.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The notifier intentionally supports arbitrary external command execution that is broader than simple notification delivery. In the context of an audio translation skill, this materially expands the attack surface because routine workflow events can trigger execution of attacker-chosen host commands, turning a media-processing tool into a general code-execution primitive.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This code executes external shell commands for transcript, translation, and audio notifications via subprocess.run(..., shell=True), but there is no confirmation prompt, visible logging, or user-facing warning in this file about that behavior. Because these commands can transmit text data or trigger arbitrary side effects, the lack of disclosure makes the operation insufficiently transparent to users.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _run_text_command(self, command: str | None, text: str) -> None:
        if not command:
            return
        subprocess.run(command, input=text.encode("utf-8"), shell=True, check=True)

    def _run_audio_command(self, command: str | None, audio_file: Path) -> None:
        if not command:
Confidence
98% confidence
Finding
This executes a configured string via the system shell with shell=True, which enables arbitrary shell metacharacter parsing and command chaining. If the command value is influenced by a user, config file, environment, or untrusted workflow input, an attacker can achieve arbitrary command execution on the host; the translated/transcribed text sent to stdin does not remove that risk.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
resolved = command.format(audio_file=str(audio_file))
        else:
            resolved = f'{command} "{audio_file}"'
        subprocess.run(resolved, shell=True, check=True)

    def notify_transcript(self, text: str) -> None:
        self._run_text_command(self.transcript_command, text)
Confidence
100% confidence
Finding
This constructs a shell command from a configurable template and an audio file path, then executes it with shell=True. Because both shell expansion and Python format substitution are used, malicious command strings or crafted file paths can inject additional commands, leading to full arbitrary code execution and possible data exfiltration or system compromise.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The embedded translation guide is entirely in Chinese, and the interactive prompt later also requires Chinese-language comprehension. This imposes a specific language on users without opt-in or explanation, which is a natural-language policy violation under the locale/language rule.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The prompt shown to users during interactive translation is only in Chinese, with no fallback or language selection. That creates a locale-specific experience not clearly justified in the file.

Static analysis

No suspicious patterns detected.