Back to skill

Security audit

Spotify Controller

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real Spotify controller, but its setup guidance is too loose around dependency installation and file permissions while handling Spotify tokens.

Review before installing. Use an isolated virtual environment or locked container dependency set, pin requests, avoid system-wide package installs where possible, set the script read-only for non-deployment users such as 0644 or stricter, protect the .env file, and revoke or rotate the Spotify refresh token if it is exposed.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:41
Finding
Unpinned Third-Party Dependency Installed into the System Python Environment<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:41-49` **Vulnerability Type**: Unpinned dependency and unsafe system-wide package installation **Risk Level**: Medium ### Vulnerable Code ```bash uv pip install requests --system ``` ```text (Alternative: `pip install requests`) ``` ```dockerfile RUN uv pip install requests --system ``` ### Technical Analysis The installation instructions retrieve `requests` without specifying a reviewed version, lockfile, or integrity hash. Package resolution can therefore produce different code over time, making deployments non-reproducible and allowing a future compromised or incompatible release to be installed without further review. The `--system` option additionally installs the dependency into the shared Python environment instead of an isolated virtual environment. This expands the potential impact to other Python applications using that environment and may overwrite or conflict with system-managed packages. The package name is the legitimate `requests` package rather than an evident typosquat, and no malicious package source is explicitly configured. The risk arises from unconstrained dependency resolution and system-wide installation. ### Attack Path 1. An attacker compromises a dependency release, its distribution account, or the package source used by the runtime. 2. A user or container build follows the documented installation command. 3. The package installer resolves the unpinned dependency to the affected release. 4. Malicious installation or runtime code executes with the privileges of the installer or application. 5. Because the application imports `requests`, malicious runtime code could access process data, including the Spotify credentials loaded by the script, and perform actions available to the runtime account. ### Impact Assessment Successful exploitation could execute code with the package installer’s or Spotify controller’s privileges. Potential scope includes: - Access to ...[truncated 552 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `requests` and all transitive dependencies to reviewed versions. 2. Maintain dependency versions in a lockfile generated from a controlled environment. 3. Require package hashes, for example through a requirements file used with `pip install --require-hashes`. 4. Install packages from an explicitly configured and trusted package index. 5. Use a dedicated virtual environment rather than `--system`. 6. Run package installation as an unprivileged build user where practical. 7. Incorporate dependency vulnerability and provenance checks into the build pipeline. 8. Rebuild and review the lockfile deliberately when dependency upgrades are required. Example hardened workflow: ```bash python3 -m venv /opt/spotify-controller/venv /opt/spotify-controller/venv/bin/pip install \ --require-hashes \ -r requirements.lock ``` ]]>

T07 · Tool Hijacking and Spoofing

Warning
Location
SKILL.md:116
Finding
Group-Writable Spotify Controller Script Enables Local Tool Replacement<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:116-117` **Vulnerability Type**: Group-writable application code permitting tool hijacking **Risk Level**: Medium ### Vulnerable Code ```bash chown <runtime_user>:<runtime_group> /path/to/workspace/spotify.py chmod 664 /path/to/workspace/spotify.py ``` ### Technical Analysis File mode `664` grants write permission to both the owner and every member of `<runtime_group>`. The affected file is executable application logic that is subsequently invoked with: ```bash python3 spotify.py <command> ``` Any user or process with membership in the assigned group can alter or replace the script. The modified file would retain the expected name and invocation pattern, causing legitimate-looking Spotify commands to execute attacker-controlled Python code. This becomes particularly significant because the script runs in an environment containing three Spotify credentials. A replacement script could read these variables, misuse them, or execute other operations with the runtime user’s local permissions. The issue requires an attacker to already possess write access through the selected runtime group. It does not independently grant remote access or elevated operating-system privileges. ### Attack Path 1. The administrator follows the documentation and assigns `spotify.py` mode `664`. 2. An attacker controls another account or process that belongs to `<runtime_group>`. 3. The attacker modifies `/path/to/workspace/spotify.py` while preserving its expected filename. 4. A user, automation, or AI agent invokes `python3 spotify.py <command>`. 5. The injected Python code executes with the invoking runtime user’s privileges. 6. The injected code can read the Spotify environment variables and perform local or network actions available to that account. ### Impact Assessment Successful exploitation allows code execution as the account invoking the Spotify controller. The resulting scope can include: - Theft or m ...[truncated 495 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove group write permission and use mode `0644` or stricter: ```bash chown <runtime_user>:<runtime_group> /path/to/workspace/spotify.py chmod 644 /path/to/workspace/spotify.py ``` 2. If the runtime user does not need to modify application code, assign ownership to a dedicated deployment account or root and grant the runtime user read-only access. 3. Ensure the parent directory is also not writable by untrusted users or shared groups. 4. Mount deployed application code read-only in containers. 5. Use a narrowly scoped group containing only trusted deployment identities. 6. Verify application-file hashes or signatures before execution in sensitive deployments. 7. Keep credentials separate from writable workspace content and expose them only to the process that requires them. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Tainted flow: 'REFRESH_TOKEN' from os.environ.get (line 23, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
def get_access_token() -> str:
    ensure_env()
    r = requests.post(
        "https://accounts.spotify.com/api/token",
        data={
            "grant_type": "refresh_token",
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The code substantially matches the declared Spotify playback/device-control purpose and uses the Spotify Web API as described. Implemented commands cover status, play/pause, next/prev, volume, search, play first search result, device listing, and active-device switching. However, the description specifically claims it can 'play a specific Spotify URL,' while the implementation only accepts a track URI string for the playtrack command (e.g. spotify:track:...). There is no logic to accept or normalize open.spotify.com URLs or other Spotify URL forms. No significant undeclared capabilities are present beyond standard token refresh and API communication.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill clearly requires environment secret access and outbound network access, but it does not declare an explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, missing scope declarations weaken isolation and review controls, making it easier for the skill to access secrets or make remote requests without transparent operator approval.

External Transmission

Medium
Category
Data Exfiltration
Content
Exchange code for tokens:

```bash
curl -s -X POST "https://accounts.spotify.com/api/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=YOUR_CODE&redirect_uri=http://127.0.0.1:8888/callback&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
chown <runtime_user>:<runtime_group> /path/to/workspace/spotify.py
chmod 664 /path/to/workspace/spotify.py
```

---
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
def get_access_token() -> str:
    ensure_env()
    r = requests.post(
        "https://accounts.spotify.com/api/token",
        data={
            "grant_type": "refresh_token",
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
token = get_access_token()
    headers = kwargs.pop("headers", {})
    headers["Authorization"] = f"Bearer {token}"
    url = f"https://api.spotify.com/v1{endpoint}"
    return requests.request(method, url, headers=headers, timeout=20, **kwargs)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.