Back to skill

Security audit

lx-music-assistant

Security checks for vulnerabilities and agentic risk

Overview

This LX Music control skill is mostly coherent and disclosed, but its bundled playlist code has a real shell-command-injection risk that should be reviewed before installation.

Install only if you are comfortable granting a local assistant control over LX Music playback, favorites, lyrics/status reads, and local playlist database access. The bundled CLI should be fixed to use non-shell process execution before broad use, and users should avoid passing untrusted playlist IDs or custom database paths.

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

Error
Location
cli/lx-music-cli.js:182
Finding

Shell Command Injection Through Playlist Identifiers

Content
View full analysis
'); console.log(' Use the list command to view playlist IDs'); process.exit(1); } const dbPath3 = getLxDataDbPath(); if (!fs.existsSync(dbPath3)) { console.log(`❌ Database does not exist: ${dbPath3}`); process.exit(1); } const scriptPath2 = path.join(__dirname, 'list.py'); try { const playResult = execSync(`python "${scriptPath2}" play "${listId2}" --db "${dbPath3}"`, { encoding: 'utf-8', timeout: 10000 }); const pr = JSON.parse(playResult); if (pr.error) { console.log(`❌ ${pr.error}`); } else { console.log(`▶️ Playing playlist: ${pr.source}/${pr.sourceId}`); } } catch (err) { console.log(`❌ Playback failed: ${err.message}`); } break; } ``` ### Technical Analysis The `listsongs` and `listplay` commands obtain playlist identifiers directly from `process.argv`. These values are interpolated into command strings passed to `child_process.execSync`. `execSync` executes string commands through a system shell. E ...[truncated 1688 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
cli/lx-music-cli.js:138
Finding

Shell Command Injection Through Environment-Derived Database Paths

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
references/commands.md:3
Finding

Unpinned Global Installation of a Third-Party npm Package

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared behavior does not fully match the effective capabilities noted by analysis, especially direct local SQLite access and launching external URLs/program behaviors. Undisclosed capabilities are dangerous because they change the trust boundary: a user or orchestrator may approve a music-control skill without realizing it can read local data stores or trigger external handlers.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared behavior does not fully match the effective capabilities noted by analysis, especially direct local SQLite access and launching external URLs/program behaviors. Undisclosed capabilities are dangerous because they change the trust boundary: a user or orchestrator may approve a music-control skill without realizing it can read local data stores or trigger external handlers.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · references/open-api.md (reported line 1)May include surrounding context.

md
# 开放 API 服务

> 来源:https://lxmusic.toside.cn/desktop/open-api
> 从 v2.7.0 起支持开放 API 服务

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill explicitly instructs execution of local shell commands (node {skill_dir}/cli/lx-music-cli.js ...) but declares no permissions or allowed-tools scope. That creates an authorization gap where an agent may expose shell-capable behavior without clear confinement, making command execution and host interaction less auditable and easier to misuse.

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 · cli/list.py (reported line 94)May include surrounding context.

python
sys.exit(1)
    url = f"lxmusic://songlist/play/{source}/{sid}"
    if sys.platform == "win32":
        subprocess.run(["cmd", "/c", "start", url], shell=False)
    elif sys.platform == "darwin":
        subprocess.run(["open", url])
    else:

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 · cli/list.py (reported line 96)May include surrounding context.

python
if sys.platform == "win32":
        subprocess.run(["cmd", "/c", "start", url], shell=False)
    elif sys.platform == "darwin":
        subprocess.run(["open", url])
    else:
        subprocess.run(["xdg-open", url])
    print(json.dumps({"action": "play", "source": source, "sourceId": sid, "url": url}, ensure_ascii=False))

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 · cli/list.py (reported line 98)May include surrounding context.

python
elif sys.platform == "darwin":
        subprocess.run(["open", url])
    else:
        subprocess.run(["xdg-open", url])
    print(json.dumps({"action": "play", "source": source, "sourceId": sid, "url": url}, ensure_ascii=False))

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The CLI invokes Python through execSync with a shell-built command string containing dbPath and listId-derived values elsewhere in the file, creating unnecessary command-execution risk if those values contain shell metacharacters. In skill context this is more concerning because the feature reaches into a local application database, expanding access beyond simple playback control into local data inspection.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest limits playlist functionality to '本地歌单查询' (local playlist querying), but the openlist and playlist commands operate on externally supplied source/playlist IDs and trigger opening or playback of those songlists. This is broader than local playlist querying and changes playback state based on remote playlist identifiers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation states that enabling the feature starts a local HTTP service for third-party software, but it does not prominently warn users about the security implications of exposing playback metadata and control endpoints on localhost. In a skill context, this can normalize unsafe assumptions and lead integrators to enable the API without understanding that other local processes or browser-based requests may interact with the player.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The control endpoint section documents unauthenticated actions such as play, pause, seek, volume changes, and collect/uncollect without warning that any caller able to reach the local service may trigger them without additional user confirmation. In this skill, those endpoints are directly relevant because the assistant is designed to invoke them automatically, increasing the chance that users overlook the absence of authorization safeguards.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation exposes state-changing scheme URLs such as collect, uncollect, and dislike that can directly modify user data or preferences, but it does not warn about accidental or unintended invocation. Because custom scheme links can be triggered from browsers, scripts, or other local applications, users or downstream integrators may invoke these actions without understanding the side effects, leading to unauthorized preference changes or playlist/library manipulation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest describes playback control, search, volume, status/lyrics, favorites, and local playlist queries, but does not mention marking tracks as 'disliked' or 'not liked'. The help text and command handler add this separate preference-modification action, which goes beyond the declared user-facing scope.

Content

No source excerpt is available for this finding.