Back to skill

Security audit

desktop-music-launcher

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed desktop music launcher/controller with some expected local automation and Spotify token handling risks, but no evidence of deception, persistence, or unrelated data access.

Install only if you are comfortable letting the skill launch local music apps, open music/search URLs, and, on macOS, use Accessibility/Automation to control Spotify or Music. Prefer SPOTIFY_ACCESS_TOKEN over --spotify-token, use a short-lived limited-scope token, and avoid pasting tokens into shared logs or shell history.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Note
Location
scripts/music_skill.py:658
Finding

Spotify Access Token Exposure Through Command-Line Arguments

Content
View full analysis
Optional[str]: return cli_token or os.environ.get("SPOTIFY_ACCESS_TOKEN") or None ``` ```python p_play.add_argument( "--spotify-token", dest="spotify_token", help="Optional: Spotify Web API access token; if omitted, SPOTIFY_ACCESS_TOKEN may be read from the environment", ) ``` The documented usage also encourages supplying the credential through the environment: ```bash export SPOTIFY_ACCESS_TOKEN="" python3 scripts/music_skill.py play "Phoenix Legend Lotus Pond Moonlight" --app spotify --control-mode macos-ui --spotify-market JP ``` ### Technical Analysis The `--spotify-token` option permits an OAuth bearer token to be supplied directly in the process command line. Command-line arguments can be recorded in shell history and may be observable through process-inspection interfaces, endpoint monitoring products, diagnostic tools, or process-accounting systems. The environment-variable fallback avoids placing the token directly in shell history when used carefully, but environment variables may still be inherited by child processes or exposed to sufficiently privileged local inspection tools. The token is sent only to the fixed official endpoint `https://api.spotify.com/v1/search`, so the network transmission itself is consistent with the declared Spotify lookup feature. The vulnerability concerns local credential handling rather than unauthorized exfiltration by the Skill. ### Attack Path 1. A user invokes the Skill with `--spotify-token `. 2. The bearer token becomes part of the Python process command line and may also remain in shell history. 3. A malicious local process, another user with applicabl ...[truncated 958 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (28)

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SELF_CHECK.md (reported line 44)May include surrounding context.

md
## 5. 安全审计

- [x] 未使用 `curl | bash`
- [x] 未下载远程执行脚本
- [x] 未使用 Base64 混淆执行
- [x] 未尝试读取浏览器 Cookie / token

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · SKILL.md (reported line 183)May include surrounding context.

md
## 5. 安全审计

- [x] 未使用 `curl | bash`
- [x] 未下载远程执行脚本
- [x] 未使用 Base64 混淆执行
- [x] 未尝试读取浏览器 Cookie / token

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · examples/usage-example.md (reported line 52)May include surrounding context.

8. Spotify 精确点播(推荐)

bash
export SPOTIFY_ACCESS_TOKEN="<你的 access token>"
python3 scripts/music_skill.py play "凤凰传奇 荷塘月色" --app spotify --control-mode macos-ui --spotify-market JP

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill performs outbound network access to Spotify's API but the detected network capability is reportedly undeclared. Hidden or undocumented egress increases risk because user queries and authorization headers can leave the local system without an explicit permission grant.

Content

No source excerpt is available for this finding.

Lp1

High
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill performs outbound network access to Spotify's API but the detected network capability is reportedly undeclared. Hidden or undocumented egress increases risk because user queries and authorization headers can leave the local system without an explicit permission grant.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 242)May include surrounding context.

md
- macOS 下支持 Spotify / Music.app 的 AppleScript 控制
- 支持 play/pause/next/previous/status
- 支持对查询执行“尽力开始播放”的 UI 自动化模式(需要辅助功能 + 自动化权限)
- 对 Spotify 提供可选的 Web API 精确搜索 + 轨道 URI 播放链路(需要用户自行提供 access token)
默认只做本机安全操作:扫描、启动可执行文件、打开 URI/网页、将本地文件交给播放器、
在 macOS 上调用 osascript 执行可审计的 AppleScript。
"""

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · SELF_CHECK.md (reported line 83)May include surrounding context.

md
- macOS 下支持 Spotify / Music.app 的 AppleScript 控制
- 支持 play/pause/next/previous/status
- 支持对查询执行“尽力开始播放”的 UI 自动化模式(需要辅助功能 + 自动化权限)
- 对 Spotify 提供可选的 Web API 精确搜索 + 轨道 URI 播放链路(需要用户自行提供 access token)
默认只做本机安全操作:扫描、启动可执行文件、打开 URI/网页、将本地文件交给播放器、
在 macOS 上调用 osascript 执行可审计的 AppleScript。
"""

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/music_skill.py (reported line 10)May include surrounding context.

python
- macOS 下支持 Spotify / Music.app 的 AppleScript 控制
- 支持 play/pause/next/previous/status
- 支持对查询执行“尽力开始播放”的 UI 自动化模式(需要辅助功能 + 自动化权限)
- 对 Spotify 提供可选的 Web API 精确搜索 + 轨道 URI 播放链路(需要用户自行提供 access token)
默认只做本机安全操作:扫描、启动可执行文件、打开 URI/网页、将本地文件交给播放器、
在 macOS 上调用 osascript 执行可审计的 AppleScript。
"""

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/music_skill.py (reported line 434)May include surrounding context.

python
- macOS 下支持 Spotify / Music.app 的 AppleScript 控制
- 支持 play/pause/next/previous/status
- 支持对查询执行“尽力开始播放”的 UI 自动化模式(需要辅助功能 + 自动化权限)
- 对 Spotify 提供可选的 Web API 精确搜索 + 轨道 URI 播放链路(需要用户自行提供 access token)
默认只做本机安全操作:扫描、启动可执行文件、打开 URI/网页、将本地文件交给播放器、
在 macOS 上调用 osascript 执行可审计的 AppleScript。
"""

Credential Access

High
Category
Privilege Escalation
Confidence
88% confidence
Finding

Accepting a bearer token on the command line is risky because CLI arguments are often exposed through shell history, process listings, telemetry, or job logs. In this skill that creates a realistic secret-handling weakness even though the token is user-supplied for a legitimate feature.

Content

Scanner excerpt · scripts/music_skill.py (reported line 660)May include surrounding context.

python
p_play.add_argument(
        "--spotify-token",
        dest="spotify_token",
        help="可选:Spotify Web API access token;未提供时,也可从环境变量 SPOTIFY_ACCESS_TOKEN 读取",
    )
    p_play.add_argument(
        "--spotify-market",

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file contains all user-facing guidance in a single forced language, which can violate language/locale policy when no user opt-in or alternative is provided. There is no indication that the skill is region-specific or intentionally limited to Chinese-speaking users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown example instructs users to export an access token, which is a sensitive credential, but provides no warning about keeping the token private, avoiding shell history exposure, or using a limited-scope token. Under the markdown-file criteria, examples that affect privacy or credentials should disclose the risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains natural-language user-facing descriptions that assume Chinese as the only language, including the module docstring and command/help text. The policy requires avoiding forced language or locale choices unless the skill offers opt-in or clearly documents a justified locale restriction.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/music_skill.py (reported line 73)May include surrounding context.

python
def run_command(command: List[str], check: bool = True) -> subprocess.CompletedProcess:
    return subprocess.run(command, check=check, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)


def has_osascript() -> bool:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/music_skill.py (reported line 107)May include surrounding context.

python
if current_os() == "windows":
            parts = command.split()
            if len(parts) == 1 and shutil.which(parts[0]):
                subprocess.Popen([parts[0], *extra_args])
            else:
                subprocess.Popen(command if not extra_args else f'{command} {" ".join(extra_args)}', shell=True)
        else:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

This branch uses subprocess.Popen(..., shell=True) and builds the command string by concatenating command and extra_args. If the command metadata or passed arguments contain shell metacharacters, an attacker can execute arbitrary OS commands under the user's context.

Content

Scanner excerpt · scripts/music_skill.py (reported line 109)May include surrounding context.

python
if len(parts) == 1 and shutil.which(parts[0]):
                subprocess.Popen([parts[0], *extra_args])
            else:
                subprocess.Popen(command if not extra_args else f'{command} {" ".join(extra_args)}', shell=True)
        else:
            parts = command.split()
            subprocess.Popen(parts + extra_args)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/music_skill.py (reported line 112)May include surrounding context.

python
subprocess.Popen(command if not extra_args else f'{command} {" ".join(extra_args)}', shell=True)
        else:
            parts = command.split()
            subprocess.Popen(parts + extra_args)
        return {"ok": True, "command": command, "args": extra_args}
    except Exception as exc:
        return {"ok": False, "command": command, "args": extra_args, "error": str(exc)}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/music_skill.py (reported line 183)May include surrounding context.

python
if target["matched_paths"]:
        executable = target["matched_paths"][0]
        try:
            subprocess.Popen([executable])
            return {"ok": True, "method": "path", "app": target["id"], "target": executable}
        except Exception as exc:
            return {"ok": False, "method": "path", "app": target["id"], "target": executable, "error": str(exc)}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
86% confidence
Finding

The code passes dynamically constructed AppleScript to osascript, including user-influenced values such as search queries and track URIs. Although some escaping is applied, AppleScript execution is a privileged automation boundary on macOS and mistakes in script construction can lead to unintended command execution or abusive UI automation against other apps.

Content

Scanner excerpt · scripts/music_skill.py (reported line 250)May include surrounding context.

python
return {"ok": False, "error": "当前系统缺少 osascript"}

    try:
        result = subprocess.run(
            ["osascript", "-e", script],
            capture_output=True,
            text=True,

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill sends user search queries and a bearer token to Spotify's Web API, which is an external transmission of potentially sensitive data. In context this behavior is feature-related and optional, but it still expands exposure beyond local-only operation and can leak listening intent or credentials if not clearly disclosed.

Content

Scanner excerpt · scripts/music_skill.py (reported line 365)May include surrounding context.

python
params = {"q": query, "type": "track", "limit": "1"}
    if market:
        params["market"] = market
    url = "https://api.spotify.com/v1/search?" + urllib.parse.urlencode(params)
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"})
    try:
        with urllib.request.urlopen(req, timeout=12) as resp:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/music_skill.py (reported line 532)May include surrounding context.

python
if target["matched_paths"]:
                executable = target["matched_paths"][0]
                try:
                    subprocess.Popen([executable, real])
                    result["open_result"] = {"ok": True, "method": "path+arg", "app": target["id"], "target": real}
                except Exception as exc:
                    result["open_result"] = {"ok": False, "error": str(exc)}

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/music_skill.py (reported line 548)May include surrounding context.

python
if target["matched_paths"]:
                executable = target["matched_paths"][0]
                try:
                    subprocess.Popen([executable, url])
                    result["open_result"] = {"ok": True, "method": "path+arg", "app": target["id"], "target": url}
                except Exception as exc:
                    result["open_result"] = {"ok": False, "error": str(exc)}

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The parser help strings and related user-facing CLI text are all Chinese-only, which constitutes a natural-language locale restriction. There is no indication that the user can choose another language or that the tool is intentionally limited to a Chinese-language environment.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/smoke_check.py (reported line 14)May include surrounding context.

python
SCRIPT = ROOT / "scripts" / "music_skill.py"

def run(*args: str):
    result = subprocess.run([sys.executable, str(SCRIPT), *args], capture_output=True, text=True, check=True)
    return json.loads(result.stdout)

def main():

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manual test documentation instructs users to pass a Spotify access token via an environment variable but provides no warning about treating the token as sensitive, limiting scope, or avoiding shell history/log exposure. In a testing context this can lead to credential leakage through copied commands, terminal recordings, CI logs, or shared troubleshooting output, especially because the token is shown inline with the command format.

Content

No source excerpt is available for this finding.