Back to skill

Security audit

Chart Splat

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its preferred unpinned npx execution and configurable API endpoint create review-worthy supply-chain and credential exposure risks.

Install only if you are comfortable sending chart data to Chart Splat and using an npm CLI. Prefer a pinned, reviewed `chartsplat-cli` version, avoid sensitive chart contents unless approved, restrict network egress to the Chart Splat API, and do not set `CHARTSPLAT_API_URL` except in a trusted environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:43
Finding
Unpinned npm Package Is Automatically Downloaded and Executed<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:23-27`, `SKILL.md:43-48`, and `SKILL.md:66-71` **Vulnerability Type**: Unpinned runtime dependency execution **Risk Level**: Medium ### Vulnerable Code ```yaml install: - kind: node package: chartsplat-cli bins: [chartsplat] label: "Install Chart Splat CLI via npm" ``` ```bash npx -y chartsplat-cli bar \ --labels "Q1,Q2,Q3,Q4" \ --data "50,75,60,90" \ --title "Quarterly Revenue" \ --color "#8b5cf6" \ -o chart.png ``` Additional documented invocations execute the same unpinned package: ```bash npx -y chartsplat-cli line -l "Mon,Tue,Wed,Thu,Fri" -d "100,200,150,300,250" -o line.png npx -y chartsplat-cli bar -l "A,B,C" -d "10,20,30" -o bar.png npx -y chartsplat-cli pie -l "Red,Blue,Green" -d "30,50,20" -o pie.png npx -y chartsplat-cli doughnut -l "Yes,No,Maybe" -d "60,25,15" -o doughnut.png npx -y chartsplat-cli radar -l "Speed,Power,Range,Durability,Precision" -d "80,90,70,85,95" -o radar.png npx -y chartsplat-cli polararea -l "N,E,S,W" -d "40,30,50,20" -o polar.png npx -y chartsplat-cli candlestick --config ohlc.json -o chart.png ``` ### Technical Analysis The Skill recommends executing `chartsplat-cli` through `npx -y` without an exact package version or integrity-protected lockfile. The `-y` option suppresses confirmation, allowing npm to download and execute the package automatically. Because package resolution is not pinned, the effective executable can change after the Skill has been reviewed. A future release, compromised maintainer account, compromised registry artifact, or dependency-chain compromise could introduce arbitrary lifecycle or runtime code. That code would execute under the permissions of the user or Agent running the Skill. The chart-rendering task does not inherently require downloading a mutable executable on every invocation. This behavior therefore grants the dependency supply chain more authority than is necessary. ### Attack Path 1. An at ...[truncated 1326 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `chartsplat-cli` to a reviewed exact version, for example: ```bash npx --no-install chartsplat-cli ``` after installing a fixed version during a controlled setup step. 2. Declare the exact version rather than a floating package name: ```yaml package: chartsplat-cli@<reviewed-exact-version> ``` 3. Include a lockfile containing registry URLs and integrity hashes, and enforce reproducible installation with `npm ci`. 4. Avoid `npx -y` for production or Agent runtime execution. Install dependencies in a controlled build or provisioning phase and execute only the locally verified binary. 5. Use a trusted registry and verify package provenance, signatures, maintainers, and published integrity metadata. 6. Audit and pin transitive dependencies. Add automated dependency monitoring, but require review before accepting upgrades. 7. Run the CLI in a restricted environment with: - Minimal filesystem access. - Only the required API credential. - Network egress limited to the documented Chart Splat endpoint. - No access to unrelated workspace secrets. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate-chart.js:17
Finding
API Credential and Complete Chart Payload Can Be Sent to an Unrestricted Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate-chart.js:17-18`, `scripts/generate-chart.js:27-35`, and `scripts/generate-chart.js:58-60` **Vulnerability Type**: Unrestricted credential-bearing network destination **Risk Level**: Medium ### Vulnerable Code ```js const API_URL = process.env.CHARTSPLAT_API_URL || 'https://api.chartsplat.com'; const API_KEY = process.env.CHARTSPLAT_API_KEY; ``` ```js async function generateChart(config) { const response = await fetch(`${API_URL}/chart`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': API_KEY, }, body: JSON.stringify(config), }); if (!response.ok) { const error = await response.text(); throw new Error(`API error (${response.status}): ${error}`); } const result = await response.json(); return result.image; } ``` The config-file mode reads and transmits the complete supplied JSON object: ```js const config = JSON.parse(fs.readFileSync(configFile, 'utf-8')); const image = await generateChart(config); const base64 = image.replace(/^data:image\/png;base64,/, ''); ``` ### Technical Analysis Remote transmission of chart data is part of the declared server-side rendering functionality. However, the helper script permits `CHARTSPLAT_API_URL` to select any URL without validating: - The `https:` protocol. - The expected `api.chartsplat.com` hostname. - The destination port. - Embedded URL credentials. - Whether the destination is an approved service origin. The script then attaches `CHARTSPLAT_API_KEY` and serializes the complete chart configuration to that destination. Config-file mode accepts an arbitrary JSON object and sends it without schema validation or a warning that its contents leave the local environment. Consequently, a mistaken or attacker-controlled environment setting can redirect both the credential and chart data to an unintended server. A URL using plain HTTP can expose the same information to ne ...[truncated 1628 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the endpoint override if custom API hosts are not required: ```js const API_URL = 'https://api.chartsplat.com'; ``` 2. If custom endpoints are necessary, parse and validate the URL before sending credentials: ```js const apiUrl = new URL( process.env.CHARTSPLAT_API_URL || 'https://api.chartsplat.com' ); const allowedHosts = new Set(['api.chartsplat.com']); if ( apiUrl.protocol !== 'https:' || !allowedHosts.has(apiUrl.hostname) || apiUrl.username || apiUrl.password ) { throw new Error('Unapproved Chart Splat API endpoint'); } ``` 3. Restrict approved ports to the expected HTTPS port and reject malformed or ambiguous URLs. 4. Disable redirects or verify that every redirect remains on the approved HTTPS origin before sending or forwarding credentials. 5. Validate config files against an explicit schema. Permit only documented chart fields and reject unexpected properties that may contain unrelated secrets. 6. Display a clear warning that chart labels, values, titles, and configuration metadata are transmitted to a third-party rendering service. 7. Advise users not to submit credentials, personal data, or other sensitive information unless the service's privacy and retention controls have been reviewed. 8. Use a narrowly scoped, revocable API key and rotate it immediately if an unintended endpoint may have received it. 9. Apply network egress controls so the helper process can connect only to the approved Chart Splat API origin. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (18)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The primary purpose matches the description: the code generates charts via the Chart Splat API and produces PNG output. However, there is a material feature mismatch because the description explicitly claims support for candlestick/OHLC charts, while the implementation only allows line, bar, pie, doughnut, radar, and polarArea. The local file write behavior is an implementation detail for a CLI tool rather than a separate primary capability, so it is only a minor undeclared behavior. Overall, this should be flagged as a mismatch due to overstated supported chart types.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares environment and network requirements but does not define an explicit tool scope such as permissions or allowed-tools. That makes its execution boundary ambiguous, increasing the chance an agent grants broader access than intended when handling user-supplied chart data and API-key-backed network calls.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger text is broad enough to activate on many generic requests to create or visualize data, which can cause the agent to route user content to this skill unexpectedly. In context, that means user data may be sent to an external API and saved locally even when the user did not clearly consent to those side effects.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
The skill states a dependency on npx/network access without pinning an exact package version, which allows execution of whatever package version is current at runtime. This creates a supply-chain risk: a compromised or maliciously updated package could run arbitrary code and access the configured API key or local files.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding
The install metadata references npm execution paths without an immutable version boundary, so the runtime may fetch or execute changing upstream code. In a skill that requires network and an API key, that exposes users to package-tampering and account-token theft risks.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill does not prominently warn that chart data is transmitted to an external service and written to local PNG files. This is dangerous because users or orchestrators may pass sensitive business or personal data into the skill without realizing it leaves the local trust boundary and persists on disk.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
Running `npx -y chartsplat-cli` without a pinned version causes the latest available package to be fetched and executed at runtime. If the package or one of its transitive dependencies is compromised, arbitrary code can run with the skill's network access, local file access, and API key environment variable.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
This example uses an unpinned `npx` package invocation, exposing users to runtime package substitution or malicious updates. Because the command processes user-supplied chart content and writes files locally, a compromised package could abuse both data and filesystem access.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
This command fetches and executes `chartsplat-cli` via `npx` without a version pin, making behavior dependent on mutable upstream state. That enables supply-chain compromise leading to arbitrary code execution and possible exfiltration of the Chart Splat API key.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The unpinned `npx` invocation leaves the skill exposed to package drift and malicious package takeover. Since the skill requires network access and writes output files, the blast radius includes data leakage and arbitrary local file modification within the agent's permissions.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
Using `npx -y chartsplat-cli` without a fixed version means a later package update can silently change what code runs. In an agent environment, that is a meaningful supply-chain vulnerability because the package executes with the skill's privileges and user-provided inputs.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
This documentation instructs an unpinned `npx` execution of a remote npm package, which is a classic supply-chain weakness. A compromised package version could execute arbitrary code, harvest secrets from environment variables, or tamper with generated output.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The command relies on an unversioned npm package at runtime, so trust is placed in mutable upstream content. Given the skill's external API usage and local output handling, compromise could affect confidentiality, integrity, and availability.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
This unpinned `npx` invocation creates a supply-chain execution risk because the resolved package can change over time without review. A malicious release could run arbitrary code under the agent context and misuse both network and file-write capabilities.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The candlestick example also uses an unpinned `npx` package, so the same supply-chain risk applies here. The config-file workflow may further increase exposure because a compromised package can read and misuse local config contents before generating output.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The complex-chart example instructs users to execute an unpinned npm package at runtime, which permits silent upstream code changes. Because complex configs may include rich user data, compromise could leak sensitive chart contents as well as environment secrets.

External Transmission

Medium
Category
Data Exfiltration
Content
## Endpoint

```
POST https://api.chartsplat.com/chart
```

## Authentication
Confidence
50% 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

Low
Confidence
89% confidence
Finding
This markdown file instructs users to send an API key in HTTP headers to an external endpoint, which is a privacy- and security-relevant behavior. The document provides usage details but does not include any warning or disclosure about safeguarding credentials or the fact that request data is sent to a third-party service.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/generate-chart.js:18