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
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/statsfm.py (reported line 71)May include surrounding context.

python
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:

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Unrestricted Tool Access

Medium
Category
Excessive Agency
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.

Content

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

md
## 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

Unbounded Resource Access

Medium
Category
Excessive Agency
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.

Content

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

md
## 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

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · SKILL.md (reported line 252)May include surrounding context.

md
return "UTC"


BASE_URL = "https://api.stats.fm/api/v1"
DEFAULT_USER = os.environ.get("STATSFM_USER", "")
DEFAULT_RANGE = "4w"
DEFAULT_LIMIT = 15

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/api.md (reported line 3)May include surrounding context.

md
return "UTC"


BASE_URL = "https://api.stats.fm/api/v1"
DEFAULT_USER = os.environ.get("STATSFM_USER", "")
DEFAULT_RANGE = "4w"
DEFAULT_LIMIT = 15

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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/statsfm.py (reported line 50)May include surrounding context.

python
return "UTC"


BASE_URL = "https://api.stats.fm/api/v1"
DEFAULT_USER = os.environ.get("STATSFM_USER", "")
DEFAULT_RANGE = "4w"
DEFAULT_LIMIT = 15

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.