Back to skill

Security audit

Music Identify

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly transparent about identifying songs and using Spotify, but its Spotify queue helper contains a crafted-URI code execution flaw and its OAuth token handling is too exposed.

Review this skill before installing. Do not use the Spotify queue feature until the URI handling is fixed, and prefer a localhost OAuth callback with state validation and token files created with mode 600. Only send audio clips you are comfortable uploading to AudD, and treat the Spotify credentials, OAuth tokens, and music log as private data.

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 (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/spotify-queue.sh:108
Finding

Arbitrary Python Code Execution Through a Crafted Spotify URI

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/spotify-auth.py:27
Finding

Spotify OAuth Flow Does Not Validate a State Parameter

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/spotify-auth.py:104
Finding

Spotify OAuth Callback Server Listens on All Network Interfaces

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/spotify-auth.py:72
Finding

OAuth Tokens Are Initially Written Without Enforcing Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/spotify-queue.sh:46
Finding

Token Refresh Can Replace a Protected Token File With a More Permissive File

Content
View full analysis
"${TOKEN_FILE}.tmp" \ && mv "${TOKEN_FILE}.tmp" "$TOKEN_FILE" access_token="$new_access" ``` ### Technical Analysis The refresh process writes tokens to a predictable temporary path using normal shell redirection. The new file's permissions derive from the current umask rather than from the existing token file. Moving this temporary file over `tokens.json` replaces the original inode. Therefore, even if the user previously applied mode `0600`, the refreshed file may become readable by other local users. The predictable `.tmp` name also creates avoidable collision and local file-manipulation risk in a directory that may not have been verified as private. ### Attack Path 1. The original token file is protected with mode `0600`. 2. Spotify returns HTTP 401, causing `try_refresh` to run. 3. The script creates `tokens.json.tmp` under a permissive umask. 4. `mv` replaces the protected token file with the newly created file and its potentially broader mode. 5. Another local account reads the refreshed access and refresh tokens. ### Impact Assessment A local user who can read the replacement file can steal OAuth tokens and use the Spotify playback-read and playback-modification permissions granted to the Skill. If the containing directory is not private, the predictable temporary path may also permit disruption of refresh operations. ]]>
Remediation
View remediation
"$tmp_file"; then mv -f -- "$tmp_file" "$TOKEN_FILE" chmod 600 "$TOKEN_FILE" else rm -f -- "$tmp_file" exit 2 fi ``` Add cleanup traps so temporary credential files are removed on interruption or failure. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/spotify-queue.sh:115
Finding

Unescaped Values Are Concatenated Into JSON Responses

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The core declared purpose of song identification using the AudD API is accurately represented by the code. However, several material parts of the description are not implemented in this code chunk: there is no Spotify queueing logic, no trigger handling, and no recall functionality that reads a music log. The script only performs audio-file submission to AudD and returns normalized results. Reading the API key from a local config file is a supporting implementation detail rather than a problematic mismatch. Because the description claims broader functionality than the code actually provides, this chunk does not fully match the declared behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code chunk’s primary purpose is Spotify authentication setup, not song recognition. While Spotify integration could be a supporting part of a larger skill, the supplied description centers on identifying songs from audio and recalling recognized tracks. None of that behavior appears here: there is no audio ingestion, no AudD API usage, no command/intent handling, and no music-log access. Instead, the code exposes an undeclared capability—running an HTTP server to complete OAuth and persisting Spotify tokens—which is materially different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose centers on song recognition from audio and recall of previously identified songs, with Spotify queueing only as an optional downstream action. The actual code does not analyze audio, identify songs, call AudD, log music history, or implement any of the described triggers/query handling. Instead, it is solely a Spotify queue/status helper that manages OAuth tokens and interacts with Spotify playback endpoints. This is a materially different primary purpose from the declared description.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The skill is explicitly designed to access locally stored API keys, OAuth tokens, and client credentials. Credential access is expected for functionality, but in an agent context it is still sensitive because compromise or overbroad tool access could expose third-party account secrets and enable unauthorized Spotify actions.

Content

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

md
|---|---|---|---|
| AudD API key | `~/.config/audd/api_key` | Yes | Song identification |
| Spotify OAuth tokens | `~/.config/spotify/tokens.json` | No (optional) | Queue to Spotify |
| Spotify app credentials | `~/.config/spotify/credentials.json` | No (optional) | Token refresh |

**Security notes:**
- All credential files should be restricted: `chmod 600`.

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The documentation instructs users to place Spotify client secrets in a plaintext JSON file under the home directory. Even with 0600 permissions, storing reusable app secrets on disk increases the blast radius if the agent, host account, or filesystem is compromised.

Content

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

  1. Save credentials:
    bash
    mkdir -p ~/.config/spotify
    cat > ~/.config/spotify/credentials.json << 'EOF'
    {"client_id": "...", "client_secret": "...", "redirect_uri": "https://your-host/callback"}
    EOF
    chmod 600 ~/.config/spotify/credentials.json
    

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

This finding again reflects on-disk handling of Spotify client credentials, which are sensitive and reusable. In combination with shell and file-write capabilities, plaintext credential files can be copied, overwritten, or misused by other components on the same host.

Content

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

cat > ~/.config/spotify/credentials.json << 'EOF' {"client_id": "...", "client_secret": "...", "redirect_uri": "https://your-host/callback"} EOF chmod 600 ~/.config/spotify/credentials.json

text
4. Run the auth flow: `python3 scripts/spotify-auth.py`
5. Open the printed URL in a browser, authorize, tokens save automatically

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/spotify-auth.py (reported line 11)May include surrounding context.

python
#        spotify-queue.sh status

TOKEN_FILE="$HOME/.config/spotify/tokens.json"
CREDS_FILE="$HOME/.config/spotify/credentials.json"

if [[ ! -f "$TOKEN_FILE" ]]; then
  echo '{"status":"error","message":"not authenticated. run spotify-auth.py first"}'

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/spotify-queue.sh (reported line 9)May include surrounding context.

sh
#        spotify-queue.sh status

TOKEN_FILE="$HOME/.config/spotify/tokens.json"
CREDS_FILE="$HOME/.config/spotify/credentials.json"

if [[ ! -f "$TOKEN_FILE" ]]; then
  echo '{"status":"error","message":"not authenticated. run spotify-auth.py first"}'

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares shell, network, and file-write behaviors but provides no explicit permission or allowed-tools scope. In an agent environment, missing tool scoping increases the chance the skill can invoke broader capabilities than intended, especially since it handles local files, external APIs, and persistent logging.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
| Spotify app credentials | `~/.config/spotify/credentials.json` | No (optional) | Token refresh |

**Security notes:**
- All credential files should be restricted: `chmod 600`.
- This skill does not read, store, or access any platform tokens (Telegram, Discord, etc.). Audio file download from messaging platforms is handled by the host agent, not by this skill.

## Trigger

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Broad trigger phrases like 'what was that song' or 'what did I shazam' can overlap with ordinary conversation and cause the skill to activate unexpectedly. In a chat agent, overbroad activation can expose prior music-log contents or trigger file reads/network actions without clear user intent.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The skill persists an AudD API key and logs identified songs across sessions. Persistence is functionally necessary, but it increases privacy and abuse risk because both credentials and user activity history remain available for later access, including potentially unintended recall queries.

Content

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

  1. Sign up at https://audd.io (free tier: 300 requests, no credit card)
  2. Save key:
    bash
    mkdir -p ~/.config/audd
    echo "YOUR_KEY" > ~/.config/audd/api_key
    chmod 600 ~/.config/audd/api_key
    

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
   mkdir -p ~/.config/audd
   echo "YOUR_KEY" > ~/.config/audd/api_key
   chmod 600 ~/.config/audd/api_key

Spotify Integration (optional)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
   mkdir -p ~/.config/audd
   echo "YOUR_KEY" > ~/.config/audd/api_key
   chmod 600 ~/.config/audd/api_key

Spotify Integration (optional)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
   mkdir -p ~/.config/audd
   echo "YOUR_KEY" > ~/.config/audd/api_key
   chmod 600 ~/.config/audd/api_key

Spotify Integration (optional)

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

md
# AudD API Reference (Summary)

## Endpoint
- POST https://api.audd.io/

## Parameters (multipart/form-data)
- `file`: Audio file to identify (OGG/Opus accepted)

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This script makes an outbound network request to api.audd.io and sends user-supplied audio plus an authentication token. While external transmission is expected for song identification, it is still security-relevant because it transfers potentially sensitive voice/audio content outside the local trust boundary; the skill context increases concern because voice messages may contain more than just music.

Content

Scanner excerpt · scripts/identify.sh (reported line 27)May include surrounding context.

sh
exit 2
fi

response="$(curl -sS -F "file=@${audio_path}" -F "api_token=${api_key}" -F "return=spotify" https://api.audd.io/ || true)"

if [[ -z "$response" ]]; then
  echo '{"status":"error","message":"empty api response"}'

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script uploads the provided audio file and the AudD API token to a third-party service, but the script itself contains no mechanism for user disclosure, consent, or minimization of shared data. In a skill that may trigger on voice messages, this can expose user audio content to an external processor unexpectedly, creating privacy and compliance risk even if the behavior is core to the feature.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes identifying songs via AudD and optionally queueing them to Spotify, but this file implements a separate OAuth callback server that obtains Spotify access/refresh tokens and writes them to disk. While Spotify integration is mentioned, this operational behavior is significantly broader than simple song identification and is not reflected in the manifest description for this script's role.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

OAuth tokens are written to disk automatically with no prior notice, consent prompt, or file-permission hardening. If the host is multi-user, backed up insecurely, or compromised later, the stored refresh token can provide persistent access to the user's Spotify account within the granted scopes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The callback server listens on 0.0.0.0, exposing the OAuth callback handler on all network interfaces instead of only localhost. On a shared network or if port forwarding/Tailscale Serve is involved, another host may be able to send spoofed requests or race the callback flow, increasing the risk of unauthorized token handling or token overwrite.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This shell script reads sensitive authentication material from local credential and token files and later updates the token file, but it provides no user-facing warning, confirmation, or explanatory disclosure about handling secrets. For code files, accessing credentials and writing authentication data should have some visible disclosure unless clearly communicated elsewhere in the skill description, which is not present in this file.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/spotify-queue.sh (reported line 30)May include surrounding context.

sh
# Try a request; if 401, refresh token
try_refresh() {
  local response
  response=$(curl -sS -X POST "https://accounts.spotify.com/api/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=refresh_token&refresh_token=${refresh_token}&client_id=${client_id}&client_secret=${client_secret}")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The token refresh request sends the refresh token, client ID, and client secret to Spotify over HTTP, and the API helper also transmits the bearer access token in subsequent requests. Although these network calls are part of the script's function, this file does not include a visible warning, print, or explanatory note that authentication data is being sent to external Spotify endpoints.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/spotify-queue.sh (reported line 62)May include surrounding context.

sh
local http_code body

  if [[ -n "$data" ]]; then
    response=$(curl -sS -w "\n%{http_code}" -X "$method" "$url" \
      -H "Authorization: Bearer ${access_token}" \
      -H "Content-Type: application/json" \
      -d "$data")

Static analysis

No suspicious patterns detected.