Back to skill

Security audit

qwen3-tts-local-inference

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local text-to-speech skill with expected model downloads and audio output, but users should be aware of voice-cloning consent and supply-chain risks.

Install only in an isolated environment, review or pin dependencies and model revisions if reproducibility matters, and use voice cloning only with permission from the speaker. Generated WAV files and reference audio may contain sensitive voice data, so store and share them carefully.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unpinned Third-Party Dependencies and Mutable Model Revisions

Content
View full analysis

Vulnerability Details

File Location: scripts/requirements.txt:1-4, scripts/setup.sh:57-66, scripts/download_models.py:33-49, and scripts/inference.py:62-82
Vulnerability Type: Supply-chain exposure through unpinned packages and model artifacts
Risk Level: Medium

Vulnerable Code

scripts/requirements.txt:1-4:

text
qwen-tts
soundfile
torch
huggingface_hub

scripts/setup.sh:57-66:

bash
# Upgrade pip first
pip install --upgrade pip setuptools wheel

# Install qwen-tts and dependencies
echo "Installing qwen-tts (this may take several minutes)..."
pip install -r scripts/requirements.txt

# Download models
echo "Downloading models..."
python scripts/download_models.py

scripts/download_models.py:33-49:

python
def download_model(model_id: str, dest_dir: Path) -> bool:
    """Download a single model from HuggingFace Hub to *dest_dir*."""
    from huggingface_hub import snapshot_download

    local_name = model_id.replace("/", "--")
    local_path = dest_dir / local_name

    if local_path.is_dir() and any(local_path.iterdir()):
        logger.info("Already present: %s  ->  %s", model_id, local_path)
        return True

    logger.info("Downloading %s  ->  %s ...", model_id, local_path)
    try:
        snapshot_download(
            model_id,
            local_dir=str(local_path),
        )

scripts/inference.py:62-82:

python
model_id = MODEL_VARIANTS[variant]
local_path = self._local_model_path(variant)

load_source = str(local_path) if local_path else model_id
logger.info(
    "Loading '%s' from %s on %s [%s] ...",
    variant,
    "local cache" if local_path else "HuggingFace Hub",
    DEVICE,
    DTYPE,
)

load_kwargs: dict = {
    "device_map": DEVICE,
    "dtype": _resolve_dtype(),
}
if DEVICE.startswith("cuda") and DTYPE in ("float16", "bfloat16"):
    load_kwargs["attn_implementation"] = "flash_attention_2"

start = time.time()
self._model = Qwen3TTSModel.from_pretrained(load_source, **load_kwargs)
...[truncated 3011 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to an exact, reviewed version.
  2. Generate a lockfile that captures all transitive dependencies.
  3. Record cryptographic hashes and install with hash verification, such as pip install --require-hashes.
  4. Pin pip, setuptools, and wheel instead of upgrading them to unconstrained latest releases.
  5. Use a trusted package index explicitly and prevent unintended fallback to alternative indexes.
  6. Add automated dependency vulnerability, provenance, and license scanning to the release process.
  7. Pass a verified immutable commit SHA through the revision argument of every snapshot_download() and from_pretrained() call.
  8. Record and verify checksums for downloaded model files or manifests.
  9. Add an offline-only mode using local_files_only=True, and preferably make it the default during inference after explicit setup.
  10. Fail closed when an expected local model is missing rather than silently retrieving a mutable remote revision.
  11. Review model artifact formats and disable loading mechanisms that can deserialize arbitrary Python objects.
  12. Document the exact package lockfile, model commit identifiers, checksums, and update-review procedure required to reproduce an audited installation.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description describes the overall skill as a local text-to-speech inference tool with voice cloning/design features and offline generation. However, the provided code chunk only downloads model files using huggingface_hub.snapshot_download. Its primary purpose is model acquisition/setup, which requires network access, not direct speech generation. While model downloading may support the broader skill, this specific code chunk does not actually implement the declared TTS behavior and introduces an undeclared network-accessing capability. Therefore this chunk does not accurately represent the declared purpose.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documents voice cloning from a short reference clip without warning about consent, impersonation, and privacy risks. In this context, the capability directly enables creation of synthetic speech resembling another person, which can facilitate deception, harassment, or misuse of personal audio if operators are not explicitly cautioned.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code falls back to model_id and calls Qwen3TTSModel.from_pretrained(load_source, ...) when no populated local cache directory exists, which can trigger a network fetch from HuggingFace Hub. That behavior contradicts the skill description's claim of operating entirely offline after model download, and in restricted or high-assurance environments it can cause unintended outbound network access, dependency drift, or retrieval of unpinned model artifacts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The voice-cloning path accepts reference audio and synthesizes a cloned voice, then saves the result to a WAV file. While the file write is logged, there is no user-facing warning in the docstring or surrounding comments that this operation stores potentially sensitive biometric-style voice output on disk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency qwen-tts is unpinned, so installs may resolve to different versions over time. That creates supply-chain and reproducibility risk because a future compromised or breaking release could be installed without review.

Content

Scanner excerpt · scripts/requirements.txt (reported line 1)May include surrounding context.

text
qwen-tts
soundfile
torch
huggingface_hub

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency soundfile is unpinned, which means environment builds are not reproducible and may silently pick up newer releases. If an upstream release introduces a vulnerability or malicious package update, consumers of this skill could install it unknowingly.

Content

Scanner excerpt · scripts/requirements.txt (reported line 2)May include surrounding context.

text
qwen-tts
soundfile
torch
huggingface_hub

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency torch is unpinned, which is more concerning than a typical library because PyTorch has a large attack surface and a history of security advisories. An unpinned install could pull in a vulnerable release, increasing risk of code execution, denial of service, or unsafe model-loading behavior depending on how the skill uses it.

Content

Scanner excerpt · scripts/requirements.txt (reported line 3)May include surrounding context.

text
qwen-tts
soundfile
torch
huggingface_hub

Unverifiable Dependency: torch has 16 known advisory(ies) (CVE-2025-2953 (PyTorch susceptible to local Denial of Service); CVE-2022-45907 (PyTorch vulnerable to arbitrary code execution); CVE-2025-32434 (PyTorch: `torch.load` with `weights_only=True` leads to remote code execution) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding

torch has known security advisories, and because no version is pinned, it is impossible to verify whether the installed release is affected. In this skill's context, which performs local model inference and may handle model artifacts, that uncertainty is more significant because vulnerable PyTorch versions can expose denial-of-service or code-execution paths.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency huggingface_hub is unpinned, so installs may vary across systems and over time. In a model-download workflow, this increases supply-chain risk because behavior and transitive dependencies can change without explicit approval.

Content

Scanner excerpt · scripts/requirements.txt (reported line 4)May include surrounding context.

text
qwen-tts
soundfile
torch
huggingface_hub