Back to skill

Security audit

fishaudio-tts

Security checks for vulnerabilities and agentic risk

Overview

This FishAudio TTS skill mostly matches its stated purpose, but it needs review because it automatically reads a shared TOOLS.md file for credentials and proxy settings before sending requests to a cloud API.

Review before installing. Prefer setting FISH_AUDIO_API_KEY explicitly and avoid storing secrets in a shared TOOLS.md file. Do not submit confidential, regulated, or internal text unless you are comfortable sending it to FishAudio, and consider pinning dependencies in a virtual 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

Warning
Location
fish_tts.py:31
Finding

Broad plaintext API-key discovery from shared Agent configuration

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:24
Finding

Unpinned third-party dependency installation

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (8)

Tainted flow: 'headers' from os.environ.get (line 79, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · fish_tts.py (reported line 97)May include surrounding context.

python
if proxies:
            print(f"Using proxy: {proxies['https']}")
        
        response = requests.post(url, json=payload, headers=headers, proxies=proxies)
        response.raise_for_status()
        
        # Save the audio

Credential Access

High
Category
Privilege Escalation
Confidence
86% confidence
Finding

The function explicitly accesses credentials from both an environment variable and a local workspace file, giving the skill credential-access capability beyond what is minimally necessary. In this context, environment-variable access alone is normal, but combining it with opportunistic secret discovery from TOOLS.md makes the behavior materially more dangerous because it broadens the set of secrets the skill may consume without clear consent.

Content

Scanner excerpt · fish_tts.py (reported line 31)May include surrounding context.

python
}

def get_api_key():
    """Get API key from environment variable or TOOLS.md"""
    api_key = os.environ.get('FISH_AUDIO_API_KEY')
    if api_key:
        return api_key

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documentation instructs use of an external Python script that requires environment/API-key access, local file output, and network communication, but the skill declares no explicit tool scope or permissions. This creates an authorization and transparency gap: an agent or user may invoke capabilities beyond what is visibly declared, increasing the risk of secret exposure or unintended external communication.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill reads ~/.openclaw/workspace/TOOLS.md to discover proxy settings and API credentials, even though a TTS utility does not need to inspect an unrelated workspace notes file to function. This expands the skill's access to local sensitive data and can unintentionally harvest secrets or route traffic through attacker-controlled proxy settings embedded in that file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script silently searches TOOLS.md for lines resembling a FishAudio API key and uses any extracted value. Pulling credentials from a general-purpose local document without explicit user awareness creates a secret-discovery behavior that is unnecessary for the stated purpose and may cause accidental use or disclosure of credentials stored for other tools.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · fish_tts.py (reported line 77)May include surrounding context.

python
voice_id = get_voice_id(voice_name)
    
    # FishAudio API endpoint
    url = "https://api.fish.audio/v1/tts"
    
    headers = {
        "Authorization": f"Bearer {api_key}",

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 · fish_tts.py (reported line 97)May include surrounding context.

python
if proxies:
            print(f"Using proxy: {proxies['https']}")
        
        response = requests.post(url, json=payload, headers=headers, proxies=proxies)
        response.raise_for_status()
        
        # Save the audio

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill sends user-supplied text to api.fish.audio, but it does not clearly warn that all provided text leaves the local environment and is processed by an external service. In a skill context, users may pass sensitive prompts or internal content, so the lack of a prominent disclosure increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.