Back to skill

Security audit

Xiaozhi Mcp Music Official

Security checks across malware telemetry and agentic risk

Overview

This is a coherent XiaoZhi music bridge, but its playback controls can affect unrelated local processes and its remote bridge gives a configured endpoint direct control over local music tools.

Install only if you trust the XiaoZhi MCP endpoint and the music API provider. Set PLAYER_CMD to a specific trusted player such as mpv, run the skill with low privileges, and be aware that stop, pause, and resume may affect other matching local processes until the implementation tracks and controls only its own spawned player.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def play_url(url: str):
    # 直接交给本地播放器。mpv 对网络资源支持最好。
    subprocess.Popen([PLAYER_CMD, url])


@mcp.tool()
Confidence
93% confidence
Finding
subprocess.Popen([PLAYER_CMD, url])

subprocess module call

Medium
Category
Dangerous Code Execution
Content
@mcp.tool()
def stop_music() -> str:
    try:
        subprocess.run(['pkill', '-f', PLAYER_CMD], check=False)
        return '已经停止播放。'
    except Exception as e:
        return f'停止失败:{str(e)}'
Confidence
96% confidence
Finding
subprocess.run(['pkill', '-f', PLAYER_CMD], check=False)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
@mcp.tool()
def pause_music() -> str:
    try:
        subprocess.run(['pkill', '-STOP', '-f', PLAYER_CMD], check=False)
        return '音乐已暂停。'
    except Exception as e:
        return f'暂停失败:{str(e)}'
Confidence
96% confidence
Finding
subprocess.run(['pkill', '-STOP', '-f', PLAYER_CMD], check=False)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
@mcp.tool()
def resume_music() -> str:
    try:
        subprocess.run(['pkill', '-CONT', '-f', PLAYER_CMD], check=False)
        return '继续播放。'
    except Exception as e:
        return f'继续播放失败:{str(e)}'
Confidence
95% confidence
Finding
subprocess.run(['pkill', '-CONT', '-f', PLAYER_CMD], check=False)

Tainted flow: 'PLAYER_CMD' from os.environ.get (line 11, credential/environment) → subprocess.Popen (code execution)

Medium
Category
Data Flow
Content
def play_url(url: str):
    # 直接交给本地播放器。mpv 对网络资源支持最好。
    subprocess.Popen([PLAYER_CMD, url])


@mcp.tool()
Confidence
91% confidence
Finding
subprocess.Popen([PLAYER_CMD, url])

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

Medium
Category
Data Flow
Content
@mcp.tool()
def stop_music() -> str:
    try:
        subprocess.run(['pkill', '-f', PLAYER_CMD], check=False)
        return '已经停止播放。'
    except Exception as e:
        return f'停止失败:{str(e)}'
Confidence
94% confidence
Finding
subprocess.run(['pkill', '-f', PLAYER_CMD], check=False)

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

Medium
Category
Data Flow
Content
@mcp.tool()
def pause_music() -> str:
    try:
        subprocess.run(['pkill', '-STOP', '-f', PLAYER_CMD], check=False)
        return '音乐已暂停。'
    except Exception as e:
        return f'暂停失败:{str(e)}'
Confidence
94% confidence
Finding
subprocess.run(['pkill', '-STOP', '-f', PLAYER_CMD], check=False)

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

Medium
Category
Data Flow
Content
@mcp.tool()
def resume_music() -> str:
    try:
        subprocess.run(['pkill', '-CONT', '-f', PLAYER_CMD], check=False)
        return '继续播放。'
    except Exception as e:
        return f'继续播放失败:{str(e)}'
Confidence
93% confidence
Finding
subprocess.run(['pkill', '-CONT', '-f', PLAYER_CMD], check=False)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill documentation describes capabilities that access environment variables, perform network requests, and invoke a local shell/player, but it does not declare permissions or clearly bound those powers. This creates a trust and review gap: operators may deploy the skill without understanding that it can reach external services and execute a local media player command, increasing the risk of unintended command execution paths, data exposure, or unsafe runtime behavior.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The skill can send stop/pause/resume signals system-wide to processes matching a configurable pattern, which exceeds the justified capability of a music search/play bridge. In context this makes the issue more dangerous, because users would reasonably expect control over one spawned player, not arbitrary local process manipulation.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The README explicitly says the skill will call a local player to play direct music URLs, but it does not clearly warn users that this results in execution of a locally configured command on their system. In an MCP/agent context, tool-triggered local command execution is security-relevant because a misconfigured or unsafe PLAYER_CMD, or unexpected remote content passed to the player, can expand the attack surface beyond simple music playback.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill states that it uses mpv to play online URLs, but it does not prominently warn users that untrusted remote audio URLs will be fetched and handed to a local player process. Remote media handling expands attack surface through network fetching, decoder/parser vulnerabilities in the player stack, and possible privacy leakage to third-party hosts when playback is triggered.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code forwards all data received from the remote WebSocket endpoint directly into the stdin of a spawned local process, and sends that process's stdout back to the remote endpoint, with no validation, authentication hardening, permission boundary, or user warning. In this skill's context, that creates a powerful remote control channel into a local MCP tool that may perform local actions such as media playback or other privileged operations, making a compromised or malicious endpoint dangerous.

VirusTotal

65/65 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.