Back to skill

Security audit

statsfm

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent stats.fm music analytics helper, but users should be aware it can make many stats.fm API queries using a remembered username and local timezone.

Install only if you are comfortable having your stats.fm username, listening-history query parameters, and detected timezone sent to stats.fm. Avoid saving the username in memory if you share the environment or do not want future sessions to reuse it automatically, and ask the agent for narrow queries when you do not want a broad music-history deep dive.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (11)

Tainted flow: 'req' from os.environ.get (line 67, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
req.add_header('User-Agent', 'statsfm-cli/1.0')
            req.add_header('Accept', 'application/json')

            with urlopen(req, timeout=10) as response:
                data = json.loads(response.read().decode())
                return data
        except HTTPError as e:
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill explicitly relies on network access to a third-party API and indicates personal commands may use stored usernames, but it declares no tool scope or permission boundaries. Without an allowlist or permissions metadata, an agent framework may grant broader-than-necessary access, increasing the chance of unintended outbound requests or misuse of environment/network capabilities.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation instructs the agent to use personal listening-history data and to store a stats.fm username in memory, but it provides no privacy notice, consent language, retention guidance, or warning about profile visibility. This can lead to collection and persistence of personal behavioral data without adequate user awareness or minimization.

Unrestricted Tool Access

Medium
Category
Excessive Agency
Content
## How to Be Good at This

This skill is worthless if you call one command and dump the output. Music is personal. Your job is to investigate, find the story in the data, and tell it back. You're a music analyst with unlimited API calls — act like it.

### Core principles
Confidence
85% confidence
Finding
The instruction to act as if there are 'unlimited API calls' encourages unrestricted autonomous tool use and deprioritizes user-initiated minimization. In practice, this can cause excessive querying of personal listening history, unnecessary third-party data transmission, and broader exposure of user data than needed to answer the request.

Unbounded Resource Access

Medium
Category
Excessive Agency
Content
## How to Be Good at This

This skill is worthless if you call one command and dump the output. Music is personal. Your job is to investigate, find the story in the data, and tell it back. You're a music analyst with unlimited API calls — act like it.

### Core principles
Confidence
87% confidence
Finding
The skill repeatedly encourages wide, repeated, and automatic querying ('never stop at one call', 'go wide, then narrow', 'don't hold back'), creating unbounded resource consumption. This can lead to API abuse, rate-limit exhaustion, unexpected costs in hosted environments, and unnecessary processing of personal data beyond what the user requested.

External Transmission

Medium
Category
Data Exfiltration
Content
return "UTC"


BASE_URL = "https://api.stats.fm/api/v1"
DEFAULT_USER = os.environ.get("STATSFM_USER", "")
DEFAULT_RANGE = "4w"
DEFAULT_LIMIT = 15
Confidence
60% 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
return "UTC"


BASE_URL = "https://api.stats.fm/api/v1"
DEFAULT_USER = os.environ.get("STATSFM_USER", "")
DEFAULT_RANGE = "4w"
DEFAULT_LIMIT = 15
Confidence
60% 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
return "UTC"


BASE_URL = "https://api.stats.fm/api/v1"
DEFAULT_USER = os.environ.get("STATSFM_USER", "")
DEFAULT_RANGE = "4w"
DEFAULT_LIMIT = 15
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The skill sends usernames, listening-history queries, and in several commands the local timezone to stats.fm without any explicit consent or warning at the point of use. While this is core functionality for the service, these values are personal behavioral data and locale metadata, so undisclosed transmission creates a privacy risk rather than a code-execution risk.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script exposes a track-features command that queries Spotify audio-feature data, but that capability is not disclosed in the manifest/description. Hidden or undocumented capabilities reduce informed user consent and can expand data processing beyond what users expect, especially when combined with track lookups against a third-party API.

Context-Inappropriate Capability

Low
Confidence
84% confidence
Finding
The manifest describes a music data/query tool for stats.fm, Spotify, and Apple Music. While using the stats.fm API is expected, this code additionally inspects local environment state and system files such as /etc/timezone and /etc/localtime to infer the host timezone, which is not clearly justified by the stated purpose and expands the skill's access to local machine context.

Static analysis

No suspicious patterns detected.