Back to skill

Security audit

Clawtunes Play

Security checks for vulnerabilities and agentic risk

Overview

This Apple Music playback skill mostly matches its stated purpose, but it also ships an undisclosed playlist/library modification script with an AppleScript injection risk.

Review this skill before installing. Its documented playback behavior is plausible for Apple Music on macOS, but the package includes an extra playlist/library modification script that is not documented as a command and contains an AppleScript injection flaw. Install only if you trust the publisher, understand that macOS Automation/Accessibility can send UI input to Music, and are comfortable with network catalog searches and possible persistent Music library changes.

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

Error
Location
scripts/playlist_create.py:30
Finding

AppleScript Injection Through an Unsanitized Playlist Name

Content
View full analysis

Vulnerability Details

File Location: scripts/playlist_create.py, lines 30-39
Vulnerability Type: AppleScript injection leading to arbitrary command execution
Risk Level: High

Vulnerable Code

python
def ensure_playlist(name: str):
    script = f'''
    tell application "Music"
      if not (exists playlist "{name}") then
        make new user playlist with properties {{name:"{name}"}}
      end if
    end tell
    '''
    r = applescript(script)
    return r.returncode == 0, (r.stderr or r.stdout).strip()

The positional playlist command-line argument is passed to this function from main() without validation:

python
ok, msg = ensure_playlist(args.playlist)

Technical Analysis

The playlist name is inserted directly into executable AppleScript source using a Python formatted string. No escaping or parameterization is applied before the resulting script is passed to osascript.

Because the input appears inside double-quoted AppleScript string literals, a crafted playlist name can close the string and introduce additional AppleScript statements. AppleScript supports security-sensitive operations such as do shell script, application automation, and file manipulation. Consequently, this is not limited to altering playlist behavior: successful injection can execute arbitrary shell commands in the context of the user running the skill.

Escaping only quotation marks would also be insufficient as a general design. The secure approach is to keep untrusted values entirely separate from AppleScript source and pass them through osascript arguments.

Attack Path

  1. An attacker causes the skill to invoke playlist_create.py with an attacker-controlled playlist name.
  2. argparse stores that value in args.playlist.
  3. main() passes the value directly to ensure_playlist(args.playlist).
  4. ensure_playlist() interpolates the value into two executable AppleSc ...[truncated 1225 chars]
Remediation
View remediation

Remediation Suggestions

Do not construct AppleScript by interpolating untrusted input. Pass the playlist name as an argument and retrieve it through an AppleScript on run argv handler. For example:

python
def ensure_playlist(name: str):
    script = '''
    on run argv
      set playlistName to item 1 of argv
      tell application "Music"
        if not (exists playlist playlistName) then
          make new user playlist with properties {name:playlistName}
        end if
      end tell
    end run
    '''
    r = run(["osascript", "-e", script, name])
    return r.returncode == 0, (r.stderr or r.stdout).strip()

Apply the same parameterization pattern to add_track_to_playlist(), where playlist, song, and artist values are also incorporated into generated AppleScript. Additional hardening should include:

  1. Validate playlist names for expected length and reject control characters.
  2. Avoid relying on manual backslash escaping as the primary defense.
  3. Keep all user-controlled values outside executable AppleScript source.
  4. Add regression tests using names containing quotation marks, backslashes, line breaks, and AppleScript-like text.
  5. Return a nonzero process status when a security-sensitive playlist operation fails.
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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

If the underlying skill code can create playlists, modify playlists, or add catalog songs to the user's library while only declaring itself as a playback tool, that is a significant capability mismatch. Hidden state-changing actions against a user's music account are more dangerous than simple playback because they permanently modify user data and could be triggered under a much lower-trust invocation context.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the underlying skill code can create playlists, modify playlists, or add catalog songs to the user's library while only declaring itself as a playback tool, that is a significant capability mismatch. Hidden state-changing actions against a user's music account are more dangerous than simple playback because they permanently modify user data and could be triggered under a much lower-trust invocation context.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises commands that invoke shell-accessible local tools (clawtunes, python3, osascript, open) and likely network-backed catalog access, but it declares no explicit tool scope or permissions boundaries. In an agent environment, missing scope declarations can cause overbroad execution authority and make it harder to enforce least privilege or safely review what the skill is allowed to do.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The description says to use this skill whenever the user asks to play a song, artist, album, playlist, or mood in Apple Music, which is a very broad natural-language trigger surface. It does not provide exclusion conditions or negative examples clarifying when this skill should not activate versus when another music-control method should be used.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script uses osascript/System Events to activate Music and send keystrokes that change application state without any runtime confirmation or visible consent flow. UI-keystroke automation is brittle and can affect the wrong focused window or trigger unintended actions, which makes this more dangerous in an agent setting where actions may occur unexpectedly on a user's desktop.

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/catalog_play.py (reported line 15)May include surrounding context.

python
def run(cmd):
    return subprocess.run(cmd, text=True, capture_output=True)


def current_track():

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/catalog_play_experiment.py (reported line 15)May include surrounding context.

python
def run(cmd):
    return subprocess.run(cmd, text=True, capture_output=True)


def current_track():

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/clawtunes_play.py (reported line 10)May include surrounding context.

python
def run(cmd):
    return subprocess.run(cmd, text=True, capture_output=True)


def current_track():

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/playlist_create.py (reported line 14)May include surrounding context.

python
def run(cmd):
    return subprocess.run(cmd, text=True, capture_output=True)


def current_track():

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill is described as a playback helper, but this script creates playlists and permanently adds catalog songs to the user's library. That is a broader and more persistent state change than the advertised role, creating a trust and consent gap that could unexpectedly alter a user's account and local Music state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script modifies playlists and may add songs to the user's library without presenting any warning or confirmation. Silent persistent changes are dangerous in an agent skill because users may reasonably expect temporary playback, not account/library modification, and an attacker could abuse natural-language prompts to trigger unwanted changes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script uses System Events keystrokes and key presses to drive the Music UI, which is a powerful form of system-wide automation. UI-synthesis can act on the wrong window or unexpected application state, causing unintended actions beyond the requested task, especially since it relies on focus and timing rather than a narrowly scoped API.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The function sends the user's query to Apple's iTunes Search API over the network without any in-script disclosure or consent mechanism. While the destination is expected for this skill's purpose, user music requests can still reveal preferences or sensitive interests, so silent transmission is a privacy issue rather than code-execution risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

User-provided song queries are sent to Apple's iTunes Search API, disclosing user intent and listening interests to a third party without explicit notice in the script flow. While this is expected for catalog lookup, it is still a privacy-relevant behavior that should be transparent, especially in an agent context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.