Back to skill

Security audit

Data Chart Builder

Security checks for vulnerabilities and agentic risk

Overview

This chart-building skill is mostly coherent, but it allows unrestricted remote data fetches and configurable file writes that deserve review before installation.

Install only if you are comfortable with the agent fetching chart data from URLs and writing chart files to paths specified in configs. Use trusted configs and data URLs, avoid attacker-provided URLs or output paths, and prefer local files or a restricted output directory when possible.

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/chart_builder.py:38
Finding
Unrestricted Remote CSV Loading Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chart_builder.py`, lines 38-40 **Vulnerability Type**: Server-Side Request Forgery (SSRF) through an unrestricted data-source URL **Risk Level**: Medium ### Vulnerable Code ```python elif 'csv' in s: df = pd.read_csv(s['csv'], parse_dates=[s.get('date_col', 'date')]) elif 'fred' in s: ``` ### Technical Analysis The value of `series[].csv` is passed directly to `pandas.read_csv`. Pandas accepts remote URLs, so an attacker who controls or influences the chart configuration can cause the process to send a request to an attacker-selected destination. The implementation does not validate: - The URL scheme - The destination hostname or resolved IP address - Loopback, private, link-local, or reserved network ranges - Cloud instance metadata addresses - Redirect destinations - The size or content type of the response The Skill documentation explicitly advertises URL-based CSV input, making remote fetching intended behavior, but the lack of destination restrictions turns that capability into an SSRF primitive. This issue does not retrieve or execute executable code and therefore is not classified as remote payload execution. ### Attack Path 1. An attacker supplies or influences a chart configuration. 2. The attacker sets `series[].csv` to an internal or otherwise restricted URL, such as a loopback service, private-network endpoint, or cloud metadata endpoint. 3. The Agent invokes the documented chart-generation command. 4. `pd.read_csv` sends a request from the runtime environment to the supplied destination. 5. If the response can be interpreted as CSV, its contents can be processed and potentially represented in the generated chart. Errors and behavioral differences may also reveal service reachability. ### Impact Assessment Exploitation uses the network privileges of the process running the Skill. Depending on its deployment environment, an attacker may be able to: - Probe services acces ...[truncated 519 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable remote CSV loading by default and require an explicit opt-in for network sources. 2. Parse remote locations with a strict URL parser and allow only approved schemes, preferably `https`. 3. Reject URLs containing credentials or ambiguous host representations. 4. Resolve the hostname and reject every address in loopback, private, link-local, multicast, unspecified, and reserved ranges. 5. Maintain an explicit allowlist of approved data hosts where practical. 6. Disable redirects or validate the destination after every redirect. 7. Apply connection and read timeouts, response-size limits, and content-type validation. 8. Enforce outbound network restrictions at the container or firewall layer as defense in depth. 9. Consider downloading approved data through a dedicated, restricted fetcher and passing a validated local file to pandas. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/chart_builder.py:132
Finding
Configuration-Controlled Output Path Allows Overwriting Writable Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chart_builder.py`, lines 132-133 **Vulnerability Type**: Arbitrary writable-file overwrite and symbolic-link following **Risk Level**: Medium ### Vulnerable Code ```python output = config.get('output', '/tmp/chart.png') plt.savefig(output, dpi=config.get('dpi', 150), bbox_inches='tight') ``` ### Technical Analysis The chart output path is taken directly from the configuration and passed to `matplotlib.pyplot.savefig`. The path is not constrained to a dedicated output directory, normalized and checked against an approved root, or inspected for symbolic links and existing files. As a result, an attacker who controls or influences the configuration can select any path writable by the process. Matplotlib may truncate or replace an existing target while writing image data. A maliciously placed symbolic link with a supported image filename can also redirect the write to another writable file. Exploitation remains subject to filesystem permissions and Matplotlib's supported output formats. The vulnerability does not bypass operating-system permissions, but it violates least-privilege expectations by allowing chart requests to choose unrestricted filesystem destinations. ### Attack Path 1. An attacker supplies or modifies the JSON chart configuration. 2. The attacker sets `output` to an existing writable image path or to a supported image filename that is a symbolic link to another writable target. 3. The Agent invokes `chart_builder.py` using that configuration. 4. `plt.savefig` opens the selected destination and writes generated image data. 5. The prior contents of the target are replaced or corrupted. ### Impact Assessment The attacker obtains file-write capability with the privileges of the process, limited to writable paths and formats accepted by Matplotlib. Potential consequences include: - Overwriting existing chart or image assets - Corrupting writable files through a symbolic-link targ ...[truncated 414 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated chart-output directory with narrowly scoped permissions. 2. Resolve the requested path with `Path.resolve()` and verify that it remains beneath the approved output directory. 3. Accept only a safe filename rather than an arbitrary absolute or relative path. 4. Reject path traversal components and absolute paths supplied by untrusted configurations. 5. Permit only an explicit allowlist of image extensions and pass a fixed output format to `savefig`. 6. Reject symbolic links and verify each relevant path component before writing. 7. Do not overwrite existing files by default. Generate a unique server-controlled filename or use exclusive file-creation semantics. 8. Write to a securely created temporary file inside the approved directory and atomically rename it after successful rendering. 9. Run the chart process under a dedicated low-privilege account with access only to required input and output directories. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill description and trigger language are very broad, covering nearly any request involving charts, graphs, plots, or comparisons. Overbroad routing can cause this skill to activate in unintended contexts, increasing the chance that user data is sent into a toolchain that may read local files or fetch remote resources unnecessarily.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill explicitly supports URL-based CSV loading and FRED retrieval, but the documentation does not warn users that invoking it may cause outbound network access. This can surprise users, create privacy or policy violations, and make it easier to induce the agent to fetch attacker-controlled URLs or disclose metadata through external requests.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest says the skill creates charts from CSV, JSON, FRED API, or inline data. In the main create_chart path, series are loaded only from inline 'data', 'csv', or 'fred' keys; there is no branch for a JSON source even though a generic JSON loader exists elsewhere. This means the advertised JSON source capability is not implemented in the actual chart-building flow.

Static analysis

No suspicious patterns detected.