Back to skill

Security audit

Doubao Tts

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it enables third-party voice cloning without meaningful consent or privacy guardrails for sensitive voice data.

Review before installing. Only use this skill with voices you own or have explicit permission to clone, and assume uploaded audio, submitted text, voice IDs, and API credentials are processed by Volcano Engine/Bytedance. Prefer environment variables over command-line credential flags, avoid sensitive or regulated text unless approved, and be aware that generated audio is downloaded from a provider-returned URL without additional validation.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:54
Finding

Authentication Secrets Encouraged in Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:19
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/tts.py:188
Finding

Unvalidated Remote Audio URL and Unbounded Download

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code aligns with the TTS portion of the description: it calls the Volcano Engine/Doubao speech synthesis API, supports configurable synthesis options, and can synthesize using an existing cloned speaker ID. However, it does not implement actual voice cloning or training cloned voices from audio samples. There is no audio upload, dataset handling, training request, or voice creation endpoint interaction. Therefore the description overstates the implemented capabilities, making this a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly enables voice cloning from uploaded audio samples but provides no warning or safeguard around consent, impersonation, or privacy. In this context, that omission is dangerous because voice cloning is inherently dual-use and can facilitate fraud, harassment, or non-consensual biometric data processing if users are not clearly constrained and warned.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'env' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
75% confidence
Finding

The skill uses 'network' capability that is not listed in its permissions. This may indicate deceptive intent or missing permission declarations.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 27)May include surrounding context.

python
def load_dotenv():
    """Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 231)May include surrounding context.

python
def load_dotenv():
    """Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

python
def load_dotenv():
    """Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

python
def load_dotenv():
    """Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 30)May include surrounding context.

python
"""Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),
        os.path.join(script_dir, "..", ".env"),
    ]
    for path in candidates:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 31)May include surrounding context.

python
"""Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),
        os.path.join(script_dir, "..", ".env"),
    ]
    for path in candidates:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

python
"""Load environment variables from a .env file (script directory first, then parent directory). Does not overwrite existing environment variables."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),
        os.path.join(script_dir, "..", ".env"),
    ]
    for path in candidates:

Credential Access

High
Category
Privilege Escalation
Confidence
67% confidence
Finding

Searching the parent directory for .env broadens the trust boundary and can unintentionally ingest credentials from an unrelated workspace or repository root. In shared or multi-project environments, this may cause credential confusion or accidental use of the wrong secrets, though it is not active credential exfiltration.

Content

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

python
script_dir = os.path.dirname(os.path.abspath(__file__))
    candidates = [
        os.path.join(script_dir, ".env"),
        os.path.join(script_dir, "..", ".env"),
    ]
    for path in candidates:
        path = os.path.normpath(path)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The reference explicitly documents voice cloning inputs and training behavior but provides no warning that uploaded audio may contain sensitive biometric identifiers and may require consent, retention controls, and jurisdiction-specific compliance. In a skill designed to enable voice cloning, this omission can normalize unsafe use and increase the chance that users submit third-party voice samples without authorization or adequate privacy protections.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This code transmits base64-encoded user-provided voice samples and related metadata to an external third-party API for voice cloning. Because voice samples are highly sensitive biometric data and may also contain spoken personal information, sending them off-box creates meaningful privacy and consent risk if users are not clearly informed and protected.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 148)May include surrounding context.

python
body["extra_params"] = extra_params

    print(f"\nSubmitting voice cloning training (language: {LANGUAGE_MAP.get(args.language, args.language)})...")
    resp = requests.post(BASE_URL + CLONE_PATH, headers=headers, json=body, timeout=60)

    if resp.status_code != 200:
        try:

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 177)May include surrounding context.

python
while True:
        time.sleep(args.poll_interval)
        headers["X-Api-Request-Id"] = str(uuid.uuid4())
        resp = requests.post(BASE_URL + GET_VOICE_PATH, headers=headers, json=body, timeout=30)
        if resp.status_code != 200:
            print(f"Query failed: HTTP {resp.status_code}, retrying...")
            continue

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/clone_voice.py (reported line 218)May include surrounding context.

python
while True:
        time.sleep(args.poll_interval)
        headers["X-Api-Request-Id"] = str(uuid.uuid4())
        resp = requests.post(BASE_URL + GET_VOICE_PATH, headers=headers, json=body, timeout=30)
        if resp.status_code != 200:
            print(f"Query failed: HTTP {resp.status_code}, retrying...")
            continue

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

python
print(f"  Format: {args.format} {args.sample_rate}Hz")
    print(f"  Text length: {len(text)} characters")

    resp = requests.post(BASE_URL + SUBMIT_PATH, headers=headers, json=body, timeout=30)

    if resp.status_code != 200:
        try:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script sends user-provided text and authentication headers to a third-party TTS provider but does not provide an explicit privacy or data-handling warning at runtime. In a voice-cloning and TTS context, input text may contain sensitive content and the skill context increases risk because users may submit private or regulated material for synthesis.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

python
while True:
        time.sleep(args.poll_interval)
        headers["X-Api-Request-Id"] = str(uuid.uuid4())
        resp = requests.post(BASE_URL + QUERY_PATH, headers=headers, json=query_body, timeout=30)

        if resp.status_code != 200:
            print(f"Query failed: HTTP {resp.status_code}, retrying...")

Tainted flow: 'query_body' from requests.post (line 177, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

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

python
while True:
        time.sleep(args.poll_interval)
        headers["X-Api-Request-Id"] = str(uuid.uuid4())
        resp = requests.post(BASE_URL + QUERY_PATH, headers=headers, json=query_body, timeout=30)

        if resp.status_code != 200:
            print(f"Query failed: HTTP {resp.status_code}, retrying...")

Tainted flow: 'audio_url' from requests.post (line 298, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
94% confidence
Finding

The script downloads from an audio_url returned by a remote API without validating the scheme, host, or content type. If the upstream service is compromised, misconfigured, or attacker-influenced, this creates an SSRF-style trust issue and can cause the client to fetch unexpected content or large files to a local path.

Content

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

python
def download_audio(audio_url, output_path):
    print(f"\nDownloading audio to: {output_path}")
    resp = requests.get(audio_url, timeout=60, stream=True)
    if resp.status_code != 200:
        print(f"Error: Download failed, HTTP {resp.status_code}", file=sys.stderr)
        sys.exit(1)