Back to skill

Security audit

Voice Reply

Security checks for vulnerabilities and agentic risk

Overview

This voice-reply skill is mostly aligned with text-to-speech, but it has under-disclosed automatic use, credential handling, network, and environment-modifying behavior that users should review before installing.

Review this skill carefully before installing. It can automatically send assistant replies to a cloud TTS service, save and play audio locally, delete prior generated audio, store a Noiz API key in your home directory, and in some modes fetch or upload reference audio. Avoid using it for sensitive conversations unless you are comfortable with those data flows, and prefer a version that removes runtime package installation, restricts API destinations to Noiz, avoids API keys in command-line arguments, and makes automatic voice replies explicitly opt-in.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/noiz_tts.py:42
Finding

Arbitrary API Base URL Enables Disclosure of API Keys and User Content

Content
View full analysis
str: resp = requests.post( f"{base_url.rstrip('/')}/emotion-enhance", headers={"Authorization": api_key, "Content-Type": "application/json"}, json={"text": text}, timeout=timeout, ) ``` ```python try: resp = requests.post( url, headers={"Authorization": api_key}, data=data, files=files, timeout=timeout, ) finally: if files and files["file"][1]: files["file"][1].close() ``` ```python parser.add_argument("--base-url", default="https://noiz.ai/v1") ``` The timeline renderer contains the same design: ```python ap.add_argument("--base-url", default="https://noiz.ai/v1") ``` ```python resp = requests.post( url, headers={"Authorization": api_key}, data=payload, files=files, timeout=timeout, ) ``` ### Technical Analysis The scripts accept an unrestricted `--base-url` argument and construct authenticated HTTP requests from it. They do not require HTTPS, verify that the destination belongs to Noiz, or prevent redirects to another origin. Consequently, the `Authorization` value is not bound to the documented Noiz endpoint. User text, emotion-enhancement requests, and uploaded reference audio are also sent to the selected destination. Base64 normalization of the key does not provide confidentiality because base64 is reversible encoding rather than encryption. This network configurability exceeds the minimum privileges necessary for the documented Noiz TTS integration. A legitimate implementation only needs access to the expected Noiz API origin. ### Attack Path 1. An attac ...[truncated 1120 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/render_timeline.py:227
Finding

Unrestricted Reference-Audio URLs Permit SSRF and Subsequent Data Forwarding

Content
View full analysis
Tuple[Path, Optional[Path]]: """Resolve reference_audio to a path. If ref is a URL, download to temp file. Returns (path_to_use, temp_path_to_cleanup_or_None).""" if ref.startswith("http://") or ref.startswith("https://"): import requests tmp = tempfile.NamedTemporaryFile(suffix=".wav", delete=False) tmp.close() r = requests.get(ref, timeout=timeout) r.raise_for_status() Path(tmp.name).write_bytes(r.content) return Path(tmp.name), Path(tmp.name) p = Path(ref) if not p.exists(): raise FileNotFoundError(f"reference_audio not found: {ref}") return p, None ``` The downloaded response is then uploaded as reference audio: ```python ref = cfg.get("reference_audio") if ref: ref_path, ref_cleanup = _resolve_reference_audio(ref, timeout) files = { "file": ( ref_path.name, ref_path.open("rb"), "application/octet-stream", ) } elif not cfg.get("voice_id"): raise ValueError( f"Cue {cue.index}: either voice_id or reference_audio required." ) try: resp = requests.post( url, headers={"Authorization": api_key}, data=payload, files=files, timeout=timeout, ) finally: if files and files["file"][1]: files["file"][1].close() if ref_cleanup is not None: ref_cleanup.unlink(missing_ok=True) ``` The duplicate entry points use equivalent unrestricted retrieval: ```python def prepare_ref_audio(ref_audio_input: str) -> str: """Download ref audio if URL; return local p ...[truncated 2578 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/voice.py:264
Finding

Noiz API Key Is Exposed in Child-Process Command-Line Arguments

Content
View full analysis
`. 3. During the lifetime of the child process, a local observer or process-monitoring system records its command line. ...[truncated 631 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/voice.py:96
Finding

Runtime Installation of an Unpinned Third-Party Dependency

Content
View full analysis
None: if importlib.util.find_spec("requests") is None: print("[noiz] Installing requests...", file=sys.stderr) subprocess.check_call(["uv", "pip", "install", "requests"]) ``` The documentation also directs installation without a version or integrity constraint: ```bash pip3 install requests ``` ### Technical Analysis Normal Skill execution may mutate the Python environment by downloading and installing the latest package published under the name `requests`. No exact version, lock file, package hash, isolated environment, or explicit setup approval is used. The package name is legitimate and no evidence shows that the project intentionally requests a malicious dependency. Nevertheless, installing an unpinned package at runtime makes the effective dependency set change after the Skill has been reviewed. Installation and import may execute package-controlled code with the privileges of the Skill process. Automatic installation is not required for TTS execution itself and exceeds the minimum runtime behavior. Dependency preparation should be an explicit, reproducible setup operation. ### Attack Path 1. The host does not have an importable `requests` package. 2. The user invokes a Noiz-backed Skill function. 3. `ensure_noiz_ready()` automatically runs `uv pip install requests`. 4. The package resolver selects whatever compatible release and transitive dependencies are available at that time. 5. A compromised upstream release, index, mirror, resolver configuration, or transitive dependency is downloaded. 6. Package-controlled installation or import code runs under the account executing the Skill. ### Impact Assessment A c ...[truncated 536 chars]
Remediation
View remediation
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (45)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented behavior suggests a fixed, simple workflow, but the analyzed behavior includes persistent credential storage, network retrieval, dependency management, and non-Noiz backends. In a skill ecosystem, this kind of mismatch is dangerous because reviewers and users may approve it under a false assumption of limited scope.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior suggests a fixed, simple workflow, but the analyzed behavior includes persistent credential storage, network retrieval, dependency management, and non-Noiz backends. In a skill ecosystem, this kind of mismatch is dangerous because reviewers and users may approve it under a false assumption of limited scope.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented behavior suggests a fixed, simple workflow, but the analyzed behavior includes persistent credential storage, network retrieval, dependency management, and non-Noiz backends. In a skill ecosystem, this kind of mismatch is dangerous because reviewers and users may approve it under a false assumption of limited scope.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior suggests a fixed, simple workflow, but the analyzed behavior includes persistent credential storage, network retrieval, dependency management, and non-Noiz backends. In a skill ecosystem, this kind of mismatch is dangerous because reviewers and users may approve it under a false assumption of limited scope.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior suggests a fixed, simple workflow, but the analyzed behavior includes persistent credential storage, network retrieval, dependency management, and non-Noiz backends. In a skill ecosystem, this kind of mismatch is dangerous because reviewers and users may approve it under a false assumption of limited scope.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises functionality that requires shell, file I/O, environment access, and network access, but the manifest does not declare any tool scope or permissions. This under-specification makes the skill harder to review and can lead to overbroad execution in environments that rely on declared permissions for containment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

Automatically deleting the previous audio file is a destructive side effect that is only briefly mentioned as a feature and not clearly framed as a data-loss risk. Users may rely on generated audio artifacts and lose them unexpectedly, particularly if the skill runs automatically after each response.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instruction that the skill should be used automatically 'when the user speaks' is ambiguous and can trigger the skill during ordinary conversation without clear consent boundaries. Because the skill sends content to TTS and writes/plays files, unintended invocation can lead to privacy leakage, disruptive behavior, or accidental external transmission of sensitive text.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill states it uses Noiz AI TTS but does not clearly warn that reply content may be transmitted to an արտաքին third-party service. Users may unknowingly send sensitive conversation text off-device, which is especially risky for assistants handling personal, corporate, or confidential information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The metadata explicitly states that every reply is automatically converted to audio and saved to the desktop, but it does not mention any user consent, opt-in, or visibility controls. Automatic file creation in a prominent user location can expose sensitive response content, create unwanted artifacts, and surprise users who may not realize conversations are being persisted locally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script sends user-provided text and optional reference audio to a third-party TTS service, including a guest endpoint, but does not provide any explicit privacy warning, consent prompt, or data-handling notice. In a voice-reply skill, this is security-relevant because replies may contain sensitive content and reference audio may contain biometric voice data, so users may unknowingly exfiltrate private data off-device.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/render_timeline.py (reported line 116)May include surrounding context.

python
def _run_ff(cmd: List[str]) -> None:
    proc = subprocess.run(cmd, capture_output=True, text=True)
    if proc.returncode != 0:
        raise RuntimeError(f"ffmpeg failed: {' '.join(cmd)}\n{proc.stderr}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/render_timeline.py (reported line 340)May include surrounding context.

python
def _run_ff(cmd: List[str]) -> None:
    proc = subprocess.run(cmd, capture_output=True, text=True)
    if proc.returncode != 0:
        raise RuntimeError(f"ffmpeg failed: {' '.join(cmd)}\n{proc.stderr}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/render_timeline.py (reported line 127)May include surrounding context.

python
def probe_duration_ms(path: Path) -> float:
    proc = subprocess.run(
        [
            "ffprobe", "-v", "error", "-show_entries", "format=duration",
            "-of", "default=noprint_wrappers=1:nokey=1", str(path),

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script accepts arbitrary http/https URLs for reference audio and fetches them server-side without any allowlist or destination restrictions. This creates an SSRF-style capability and can be abused to reach internal services or download unexpected content, especially because the feature is broader than the stated voice-reply purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code can silently download reference audio from arbitrary URLs without notifying the user, creating both privacy and network-boundary concerns. In practice this means the skill can fetch external content and then use it for synthesis/voice-cloning workflows without transparent consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The Noiz backend sends subtitle text and optionally reference audio to an external cloud API, but the script provides no explicit user-facing warning or consent gate. This can leak sensitive transcript content and biometric voice data to a third party, which is especially concerning in a skill presented as an automatic voice reply tool.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes a reply-oriented skill that auto-generates speech and saves it to the desktop. In this file, the code renders timeline-accurate audio from an SRT plus voice-map, accepts arbitrary output and work-dir arguments, and writes a render report, with no desktop-specific behavior or reply integration.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

When --ref-audio-track is provided, the script automatically slices the source audio into per-segment reference samples for voice cloning when no explicit voice_id/reference_audio is set. That enables transformation of arbitrary input audio into cloning material, which materially expands data use and impersonation risk beyond a simple voice-reply renderer.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a skill that automatically generates speech audio for replies and saves it to the desktop using Noiz AI TTS. This file instead reads a text file, estimates sentence timings, and writes an SRT subtitle file, which is a distinct text-processing capability not implied by voice generation itself.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill persists API credentials in a dotfile under the user's home directory, which is more sensitive than ordinary voice generation and expands the blast radius if the host is shared or compromised. While permissions are set to 0600, long-lived credential storage still deserves explicit disclosure and safer secret-management practices.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Runtime package installation exceeds the expected behavior of a voice-reply skill and introduces avoidable supply-chain risk. A user invoking TTS can unknowingly cause network access and code installation into their Python environment, which increases attack surface and may violate trust boundaries.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The skill installs a Python package at runtime without explicit consent or dependency pinning. That creates a supply-chain and environment-modification risk: execution can trigger unexpected network access and pull code from external package sources into the user's environment.

Content

Scanner excerpt · scripts/tts.py (reported line 99)May include surrounding context.

python
def ensure_noiz_ready() -> None:
    if importlib.util.find_spec("requests") is None:
        print("[noiz] Installing requests...", file=sys.stderr)
        subprocess.check_call(["uv", "pip", "install", "requests"])


def detect_text_lang(text: str) -> str:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

In authenticated mode, user text, optional reference audio, and the API key are sent to an external TTS backend without meaningful in-flow disclosure. Because the skill is framed as a voice reply tool, undisclosed transmission of content and credentials to third-party services creates privacy and trust risks, especially for sensitive prompts or cloned voice material.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes a voice-reply skill that automatically generates speech, but this file also exposes broader media-processing functionality via the render and to-srt subcommands. Those features are not obvious implementation details of 'reply with voice'; they expand the skill into subtitle generation and scripted timeline rendering.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.