Back to skill

Security audit

CSV Data Explorer

Security checks for vulnerabilities and agentic risk

Overview

This CSV helper mostly matches its stated purpose, but its filter feature uses unsafe expression evaluation that could run unintended code if given a malicious condition.

Install only if you are comfortable reviewing or constraining the filter feature. Avoid running filter conditions copied from untrusted sources, use fresh output filenames to prevent overwrites, and treat exported CSVs from untrusted input as unsafe to open directly in spreadsheet software unless sanitized.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:183
Finding
Arbitrary Code Execution Through User-Controlled Pandas Query<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 183-192 **Vulnerability Type**: Unsafe expression evaluation **Risk Level**: High ### Vulnerable Code ```python if condition: # Basic safety check if any(op in condition for op in ['import', 'exec', 'eval', '__']): print("Error: Invalid condition - contains unsafe operations") return df try: filtered = df.query(condition, engine='python') print(f"Filtered from {len(df)} to {len(filtered)} rows") return filtered except: print(f"Error parsing condition: {condition}") print("Try format: 'column > value' or 'column == \"string\"'") return df ``` ### Technical Analysis The `--where` command-line argument, or the condition entered in interactive mode, is passed to `DataFrame.query()` using the Python evaluation engine. This makes the filtering expression an executable expression rather than a strictly parsed comparison. The preceding substring blacklist is not an adequate security boundary. It only rejects expressions containing `import`, `exec`, `eval`, or `__`. It does not enforce a grammar or prevent access to other objects and callable attributes available through the pandas evaluation environment. A crafted expression can therefore invoke a reachable dangerous function without containing any blocked substring. Even if the resulting expression is not a valid boolean filter, its side effects may occur before pandas reports an error. ### Attack Path 1. An attacker controls a condition supplied through `filter --where` or convinces a user or automation agent to process an attacker-provided condition. 2. The attacker constructs a pandas expression that reaches a command-execution function through an object available to the query environment while avoiding the four blocked substrings. 3. The blacklist accepts the expression. 4. `df.query(condition, engine='python')` evaluates it in the local Python pro ...[truncated 825 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not pass untrusted filtering text to `DataFrame.query()`, particularly with `engine='python'`. - Implement a strict parser for the documented filtering language. - Permit only: - Exact column names from the loaded DataFrame - Explicitly supported comparison operators - Typed string, numeric, boolean, and null literals - A small allowlist of boolean operators, if required - Construct boolean pandas masks directly after parsing, such as `df[column] > numeric_value`. - Reject function calls, attribute access, indexing into arbitrary objects, `@` references, and all syntax outside the supported grammar. - Return a failure rather than the original unfiltered DataFrame when a condition is invalid. Returning the full dataset can cause unintended disclosure or export. - Add regression tests containing known expression-injection patterns and verify that no callable object can be reached. - If a third-party expression parser is used, configure an explicit AST-node allowlist and ensure that evaluation cannot access Python globals, locals, built-ins, or object attributes. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:326
Finding
Spreadsheet Formula Injection in Exported CSV Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 326-329 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```python if format.lower() == 'csv': df.to_csv(output_path, index=False) print(f"Exported {len(df)} rows to CSV: {output_path}") ``` ### Technical Analysis CSV cells originating from an untrusted input file are exported without neutralizing values that begin with spreadsheet formula indicators such as `=`, `+`, `-`, or `@`. The CSV format itself does not execute formulas. However, spreadsheet applications may interpret these cells as formulas when a user opens the exported file. Quoting a field through normal CSV serialization does not reliably prevent spreadsheet formula evaluation. The bundled `test_data.csv` does not contain formula payloads, but the Skill is explicitly designed to process arbitrary user-provided CSV files, making malicious cell content a realistic input. ### Attack Path 1. An attacker creates a CSV file containing a formula-like value in a cell. 2. A victim processes the file with the Skill. 3. The victim uses `filter`, `select`, or interactive export to create a new CSV file. 4. `df.to_csv()` preserves the malicious value without neutralization. 5. The victim opens the generated file in spreadsheet software. 6. The spreadsheet interprets the cell as a formula. 7. Depending on spreadsheet capabilities and security settings, the formula may initiate an external request, disclose cell contents, or trigger another unsafe action. ### Impact Assessment The primary impact occurs when an exported file is opened in formula-aware spreadsheet software. Potential consequences include: - Disclosure of spreadsheet data through attacker-controlled external requests - User tracking or network callbacks - Manipulation of displayed spreadsheet content - Execution of dangerous spreadsheet features where supported and enabled This issue does not directly execute wh ...[truncated 143 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Treat all string cells as untrusted during spreadsheet-oriented CSV export. - Before export, neutralize cells whose first non-whitespace character is `=`, `+`, `-`, or `@`, commonly by prefixing the value with an apostrophe. - Consider tab and carriage-return prefixed variants when identifying dangerous values. - Make sanitized spreadsheet-compatible export the default. - If raw preservation is required, expose it as an explicit option and display a warning that the output must not be opened in formula-aware software. - Prefer a format and workflow that preserve data types without formula interpretation when interoperability requirements permit. - Add tests covering formula indicators, leading whitespace, quoted fields, and values containing delimiters or line breaks. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:153
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 153-159 **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Low ### Vulnerable Code ```markdown ## Requirements - Python 3.x - `pandas` library for data manipulation (installed automatically or via pip) - `matplotlib` library for visualizations (optional, for enhanced charts) Install missing dependencies: ```bash pip3 install pandas matplotlib ``` ``` The same unpinned installation command also appears in `README.md`, lines 70-77. ### Technical Analysis The documentation directs users to install mutable package versions from the default Python package registry. No lockfile, exact version constraints, integrity hashes, or reviewed package source is supplied. The referenced package names are legitimate, and the audit found no evidence that the project intentionally requests a typosquatted or malicious package. Nevertheless, installation is not reproducible and will resolve whatever versions the registry serves at installation time. A future compromised release, maintainer account compromise, or incompatible release could introduce unexpected installation-time or runtime behavior. ### Attack Path 1. A user follows the documented installation command. 2. `pip` contacts its configured package index and resolves the current releases of `pandas`, `matplotlib`, and their transitive dependencies. 3. No project-controlled version or hash validation ensures that the resolved artifacts match versions reviewed with this Skill. 4. A compromised or unexpectedly changed release is installed. 5. Malicious installation or runtime code executes with the privileges of the user performing installation or running the Skill. ### Impact Assessment Impact depends on the privileges used for installation and execution. A compromised dependency could potentially: - Execute code during installation or import - Read user-accessible files and environment variables - Modify data handled ...[truncated 297 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Provide a version-controlled dependency file with exact reviewed versions. - Generate and verify cryptographic hashes for every direct and transitive dependency. - Install with a command such as: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` - Use an isolated virtual environment rather than the system Python environment. - Document the expected package index and avoid untrusted additional indexes. - Add automated dependency scanning and controlled update reviews. - Keep optional visualization dependencies in a separate, pinned requirements group if they are not necessary for core operation. - Update both `SKILL.md` and `README.md` so their installation instructions remain consistent. ]]>
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The manifest description emphasizes exploring, filtering, summarizing, and visualizing CSV data directly in the terminal. However, the code includes persistent file-writing behavior by saving histogram images to PNG files and exporting filtered data to CSV/JSON, which goes beyond a purely terminal-based explorer.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The export feature writes to any user-supplied path with no validation, overwrite protection, or explicit confirmation. In an agent-driven or automated context, this can overwrite arbitrary local files the process has permission to modify, causing data loss or unintended filesystem changes.

Missing User Warnings

Low
Confidence
85% confidence
Finding
This markdown file documents commands that write output files, such as `--output filtered.csv`, but provides no user-facing warning about file creation or possible overwrite effects. Under the markdown criteria for missing user warnings, behaviors affecting user data should be disclosed.

Missing User Warnings

Low
Confidence
81% confidence
Finding
The feature description explicitly says results can be exported to new CSV/JSON files, which affects user data and filesystem state, but no caution or disclosure is provided in the skill description. A short warning would help users understand that the tool writes files as part of its operation.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The skill advertises exporting filtered results to CSV/JSON files but does not warn users about overwriting existing files or modifying local data. In a terminal workflow, this can lead to accidental data loss or unintended modification of user files, especially if output paths are reused or user-supplied.

Missing User Warnings

Low
Confidence
79% confidence
Finding
The matplotlib path saves a generated histogram image to a file, which changes the user's filesystem. The code announces the saved file afterward, but it does not disclose beforehand in help text or comments that invoking this option creates a PNG output file.

Static analysis

No suspicious patterns detected.