Back to skill

Security audit

speechfy

Security checks across malware telemetry and agentic risk

Overview

This is a coherent text-to-speech skill, but users should treat its external providers, API-key handling, helper commands, and output paths carefully.

Install only if you are comfortable sending synthesized text to Speechify or Microsoft Edge TTS. Do not pass secrets, credentials, private chats, or regulated data as input; keep SPEECHIFY_API_KEY, EDGE_TTS_CMD, and VAULT_RESOLVER under your control; and write outputs to a dedicated temporary or media directory.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (11)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""Fallback via Edge TTS (Microsoft)."""
    edge_cmd = os.environ.get("EDGE_TTS_CMD", "edge-tts")
    try:
        subprocess.run(
            [edge_cmd, "--voice", EDGE_VOICE,
             "--text", text,
             "--write-media", output_path],
Confidence
93% confidence
Finding
subprocess.run( [edge_cmd, "--voice", EDGE_VOICE, "--text", text, "--write-media", output_path], capture_output=True, timeout=60, check=True

subprocess module call

Medium
Category
Dangerous Code Execution
Content
vault_resolver = os.environ.get("VAULT_RESOLVER", "/opt/data/bin/vault-resolver")
    if os.path.isfile(vault_resolver):
        try:
            proc = subprocess.run(
                [vault_resolver, "resolve"],
                input=json.dumps({"ids": [VAULT_ITEM]}).encode(),
                capture_output=True, timeout=20
Confidence
89% confidence
Finding
proc = subprocess.run( [vault_resolver, "resolve"], input=json.dumps({"ids": [VAULT_ITEM]}).encode(), capture_output=True, timeout=20

Tainted flow: 'edge_cmd' from os.environ.get (line 111, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
"""Fallback via Edge TTS (Microsoft)."""
    edge_cmd = os.environ.get("EDGE_TTS_CMD", "edge-tts")
    try:
        subprocess.run(
            [edge_cmd, "--voice", EDGE_VOICE,
             "--text", text,
             "--write-media", output_path],
Confidence
96% confidence
Finding
subprocess.run( [edge_cmd, "--voice", EDGE_VOICE, "--text", text, "--write-media", output_path], capture_output=True, timeout=60, check=True

Tainted flow: 'vault_resolver' from os.environ.get (line 39, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Content
vault_resolver = os.environ.get("VAULT_RESOLVER", "/opt/data/bin/vault-resolver")
    if os.path.isfile(vault_resolver):
        try:
            proc = subprocess.run(
                [vault_resolver, "resolve"],
                input=json.dumps({"ids": [VAULT_ITEM]}).encode(),
                capture_output=True, timeout=20
Confidence
95% confidence
Finding
proc = subprocess.run( [vault_resolver, "resolve"], input=json.dumps({"ids": [VAULT_ITEM]}).encode(), capture_output=True, timeout=20

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documentation describes capabilities that access environment variables, invoke shell commands, and call external network services, but it does not declare corresponding permissions. This creates a trust and review gap: users or orchestrators may approve the skill without understanding that secrets may be read and text will be sent to third-party providers, increasing the risk of unintended data exposure or unsafe execution.

Context-Inappropriate Capability

Medium
Confidence
83% confidence
Finding
Implementing fallback TTS by spawning a configurable local command increases attack surface beyond a typical fixed provider integration. In this skill's context, the danger is amplified because the command path is taken from the environment, so the fallback mechanism can be repurposed to run arbitrary binaries.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README explicitly describes sending user-provided text to external TTS providers (Speechify and Edge TTS) but does not clearly warn that sensitive content will leave the local system and be processed by third parties. In an agent skill context, users may pass secrets, personal data, or internal business content to the tool, creating a real confidentiality and compliance risk even if the behavior is intended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill presents itself as a TTS helper but does not prominently warn that supplied text is transmitted to external cloud providers such as Speechify and possibly Edge TTS. If users pass sensitive content, credentials, personal data, or internal messages, that data may leave the local environment without informed consent.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill sends user-provided text to external TTS providers without any explicit disclosure or consent mechanism. If the text contains personal, confidential, or sensitive content, this can cause unintended third-party data exposure, and the skill context makes that plausible because arbitrary user text is the primary input.

Unvalidated Output Injection

High
Category
Output Handling
Content
mp3_tmp = output_path + ".tmp.mp3"
        with open(mp3_tmp, "wb") as f:
            f.write(base64.b64decode(audio_b64))
        subprocess.run(
            ["ffmpeg", "-y", "-i", mp3_tmp,
             "-c:a", "libopus", "-b:a", "32k",
             output_path],
Confidence
94% confidence
Finding
subprocess.run( ["ffmpeg", "-y", "-i", mp3_tmp, "-c:a", "libopus", "-b:a", "32k", output_path], capture_output

Unvalidated Output Injection

High
Category
Output Handling
Content
"""Fallback via Edge TTS (Microsoft)."""
    edge_cmd = os.environ.get("EDGE_TTS_CMD", "edge-tts")
    try:
        subprocess.run(
            [edge_cmd, "--voice", EDGE_VOICE,
             "--text", text,
             "--write-media", output_path],
Confidence
94% confidence
Finding
subprocess.run( [edge_cmd, "--voice", EDGE_VOICE, "--text", text, "--write-media", output_path], capture_output

VirusTotal

63/63 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.