Back to skill

Security audit

Playlistable

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-built for Spotify playlist management, but it warrants review because it stores a Spotify-connected bearer key locally and exposes playlist deletion without clear confirmation guidance.

Review before installing if you care about protecting Spotify playlist access. Treat config/auth.json as a secret, avoid committing or sharing it, and require a clear user confirmation before running delete_playlist. Also note that generated playlists are documented as public on Spotify.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/auth.mjs:91
Finding

Bearer API Key Stored Without Explicit Restrictive File Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/auth.mjs:61
Finding

Unescaped OAuth and Upstream Error Data Reflected into Local HTML Responses

Content
View full analysis
Auth failed

${error}

`); console.error(`\nAuth failed: ${error}`); ``` Token-exchange error reflection at lines 107-112: ```js } catch (err) { res.writeHead(500, { "Content-Type": "text/html" }); res.end(`

Error

${err.message}

`); console.error(`\nToken exchange error: ${err.message}`); } ``` ### Technical Analysis The callback handler places the `error` query parameter directly into an HTML response without contextual escaping. The token-exchange failure path similarly inserts `err.message`, which may include response content returned by the remote token endpoint. Because the response is declared as `text/html`, attacker-controlled markup can be interpreted by the browser. A payload containing HTML or script could therefore execute in the temporary localhost origin. The exposure is reduced because the server: - Binds only to `127.0.0.1`. - Uses a randomly selected port. - Exists only during the authentication flow. - Closes after handling the callback. These constraints make the issue lower risk, but they do not make unescaped insertion into HTML safe. ### Attack Path One applicable callback path is: 1. The authentication helper starts its temporary loopback HTTP server. 2. An attacker or compromised authorization component causes the browser to request the callback URL with an attacker-controlled `error` query value. 3. The callback handler interpolates that value into the HTML response without escaping it. 4. The browser parses the value as active HTML rather than plain text. 5. Attacker-cont ...[truncated 1008 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
`https://mcp.playlistable.io` exposes tools via Streamable HTTP transport. The `mcp-call.mjs` script sends JSON-RPC requests directly — no MCP SDK needed.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents use of environment variables and outbound network access, but it does not declare any explicit tool scope or permission boundaries. That creates an authorization transparency gap: an agent or reviewer cannot easily verify what external access the skill is expected to use, increasing the risk of over-privileged execution or unnoticed data egress.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The authentication instructions state that an API key is automatically saved to config/auth.json, but they do not warn about local secret storage, file permissions, or the sensitivity of the credential. This can lead to inadvertent exposure through weak filesystem permissions, accidental commits, or multi-user environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill exposes a delete_playlist action as a normal example without warning that it is destructive or instructing the agent to require explicit user confirmation first. In an agent setting, this increases the chance of accidental or prompt-induced deletion of user data without adequate consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The API reference documents a destructive delete_playlist operation that removes playlists from both Playlistable and Spotify, but it does not include any warning about irreversible impact or a recommendation for explicit user confirmation before use. In an agent context, this increases the risk of accidental or unauthorized destructive actions being taken on behalf of a user through ambiguous prompts, automation mistakes, or prompt injection influencing tool selection.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/auth.mjs:162