Back to skill

Security audit

Feishu Voice Tts

Security checks for vulnerabilities and agentic risk

Overview

The skill performs Feishu voice-message sending, but it also includes Feishu chat-history reading that is broader than the stated TTS purpose.

Review before installing. Use this only with a Feishu app whose permissions you are comfortable granting, and avoid enabling message/chat read scopes unless you actually need history retrieval. Do not send sensitive text through the TTS workflow unless you accept that it goes to the external MOSS service and then to Feishu.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (24)

Tainted flow: 'FEISHU_APP_ID' from os.getenv (line 16, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
def get_tenant_access_token(timeout=30):
    try:
        resp = requests.post(TOKEN_URL, json={"app_id": FEISHU_APP_ID, "app_secret": FEISHU_APP_SECRET}, timeout=timeout)
    except requests.RequestException as e:
        fail(f"获取 token 请求失败: {e}")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'app_id' from os.getenv (line 26, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
fail("请设置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量")

    try:
        resp = requests.post(TOKEN_URL, json={"app_id": app_id, "app_secret": app_secret}, timeout=timeout)
    except requests.RequestException as e:
        fail(f"获取 token 请求失败: {e}")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

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

Critical
Category
Data Flow
Content
}

    try:
        resp = requests.post(TTS_URL, json=payload, headers=headers, timeout=args.timeout)
    except requests.RequestException as e:
        fail(f"request failed: {e}")
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill is ներկայացed as text-to-speech-and-send, but the documentation also includes reading Feishu chat history using app credentials and filtering message metadata. This hidden expansion of behavior is dangerous because users may invoke a seemingly simple send action without realizing the skill can access historical conversations, creating privacy and overreach risks.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill is ներկայացed as text-to-speech-and-send, but the documentation also includes reading Feishu chat history using app credentials and filtering message metadata. This hidden expansion of behavior is dangerous because users may invoke a seemingly simple send action without realizing the skill can access historical conversations, creating privacy and overreach risks.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
"--voice_id", voice_id,
        "--output", output_path,
    ]
    env = os.environ.copy()
    env["MOSS_API_KEY"] = MOSS_API_KEY
    result = subprocess.run(cmd, capture_output=True, text=True, env=env)
    if result.returncode != 0:
Confidence
71% confidence
Finding
The code copies the entire parent environment and passes it to a child process, which can unnecessarily expose unrelated secrets to tts.py and any libraries it loads. In an agent or plugin environment where many credentials may coexist in environment variables, this broad propagation increases blast radius if the child script is compromised, modified, or overly verbose in error handling.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The script retrieves Feishu chat history even though the skill is ներկայացted as text-to-speech and message sending. This capability mismatch is dangerous because it introduces data-access functionality unrelated to the declared purpose, increasing the risk of covert collection or operator surprise around sensitive message exposure.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The code obtains a tenant token and reads message history from Feishu without a clear connection to the stated TTS send-only use case. In skill context, unexplained read access to historical conversations is more dangerous because users would reasonably expect outbound media delivery, not inbox/archive inspection.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The manifest describes a skill that converts text with MOSS-TTS and sends the resulting voice message to Feishu groups or individuals, including Feishu voice-message formatting. In this file, the code calls the MOSS-TTS API, decodes the returned audio, and saves it to a local WAV file, with no Feishu API calls, messaging logic, upload step, or waveform-message construction.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares no explicit tool scope while its documented behavior requires environment-variable access, shell execution, networking, and file output. In an agent setting, missing scope boundaries can let the runtime grant broader capabilities than users expect, increasing the chance of unintended command execution, secret access, or external communication.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill handles privacy-relevant actions such as sending Feishu messages and documenting chat-history access, yet it does not warn users about what data may be transmitted, read, or stored. Missing disclosure can lead to uninformed consent and accidental exposure of message contents, recipient identifiers, or conversation metadata.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase uses vague wording like 'or similar requests,' which weakens invocation boundaries for a skill that can send messages and interact with external systems. Over-broad activation increases the risk that unrelated user text is interpreted as authorization to generate content, contact recipients, or access connected services.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
Read access to Feishu chat history is not necessary for converting text to speech and sending a voice message. Requesting unjustified read permissions violates least-privilege principles and could expose sensitive group or direct-message content if the skill is misused or compromised.

Description-Behavior Mismatch

Medium
Confidence
98% confidence
Finding
The documentation expands the skill from TTS delivery into message-history retrieval, which is a materially different capability involving access to prior communications. Bundling that feature into the same skill broadens the attack surface and makes it easier to obtain conversation data under the guise of a benign messaging function.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
]
    env = os.environ.copy()
    env["MOSS_API_KEY"] = MOSS_API_KEY
    result = subprocess.run(cmd, capture_output=True, text=True, env=env)
    if result.returncode != 0:
        fail(f"TTS 生成失败: {result.stderr or result.stdout}")
    print(f"✓ TTS 生成完成: {output_path}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"-ac", "1", "-ar", "16000",
        "-c:a", "libopus", "-b:a", "24k", output_opus,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        fail(f"音频转码失败: {result.stderr}")
    print(f"✓ 转码完成: {output_opus}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

External Transmission

Medium
Category
Data Exfiltration
Content
"content": json.dumps({"file_key": file_key}),
    }
    try:
        resp = requests.post(url, headers=headers, json=payload, timeout=timeout)
    except requests.RequestException as e:
        fail(f"发送消息请求失败: {e}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
fail("请设置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量")

    try:
        resp = requests.post(TOKEN_URL, json={"app_id": app_id, "app_secret": app_secret}, timeout=timeout)
    except requests.RequestException as e:
        fail(f"获取 token 请求失败: {e}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
fail("请设置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量")

    try:
        resp = requests.post(TOKEN_URL, json={"app_id": app_id, "app_secret": app_secret}, timeout=timeout)
    except requests.RequestException as e:
        fail(f"获取 token 请求失败: {e}")
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script prints retrieved chat history metadata and partial content to stdout without a clear warning, consent flow, or output-safety controls. This can expose sensitive conversation data in terminals, logs, CI output, or shared operator environments, especially because the script defaults to fetching recent messages.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The inline CLI documentation describes this component as "Call MOSS-TTS and save wav file", and the code indeed only accepts an output path and writes bytes locally. That documented behavior diverges from the manifest's stated intent of converting text to speech and sending it to a Feishu group or person, indicating the implementation here does not match the advertised delivery behavior.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script transmits arbitrary user-supplied text to an external TTS provider without any explicit notice, consent checkpoint, or data-sensitivity guardrails. In a skill context, users may assume local processing and could inadvertently send secrets, personal data, or internal content to a third party.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    try:
        resp = requests.post(TTS_URL, json=payload, headers=headers, timeout=args.timeout)
    except requests.RequestException as e:
        fail(f"request failed: {e}")
Confidence
80% confidence
Finding
The code performs network transmission of user-provided content to an external domain, which is security-relevant because it creates an outbound data flow beyond the local environment. In this skill's context, that is expected for TTS, but it still poses confidentiality risk if users are not clearly informed that their text leaves the system.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The script's docstring, error messages, argument descriptions, and status output are all written in Chinese, which imposes a specific language on users. There is no opt-in, alternate locale support, or documentation indicating that the skill is intentionally limited to a Chinese-speaking environment.

Static analysis

No suspicious patterns detected.