Back to skill

Security audit

Csv Handler

Security checks for vulnerabilities and agentic risk

Overview

This CSV skill is mostly coherent, but its documented split/export features can write files unsafely and should be reviewed before installation.

Install only if you are comfortable with a CSV-processing skill that can read local project files and generate new CSV files. Use dedicated output folders, avoid splitting on untrusted column names or values, review destinations before export, and treat generated CSVs as untrusted when opening them in spreadsheet software.

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
SKILL.md:161
Finding

Spreadsheet Formula Injection in CSV Exports

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:161-174 and SKILL.md:208-214
Vulnerability Type: CSV/spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

python
def split_csv(self, df: pd.DataFrame,
              group_column: str,
              output_dir: str) -> List[str]:
    """Split CSV by column values."""
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    files = []
    for value in df[group_column].unique():
        subset = df[df[group_column] == value]
        filename = f"{group_column}_{value}.csv"
        filepath = output_path / filename
        subset.to_csv(filepath, index=False)
        files.append(str(filepath))

    return files
python
def export_csv(self, df: pd.DataFrame,
               file_path: str,
               encoding: str = 'utf-8-sig',
               delimiter: str = ',') -> str:
    """Export DataFrame to CSV."""
    df.to_csv(file_path, encoding=encoding, sep=delimiter, index=False)
    return file_path

Technical Analysis

The export methods write DataFrame cell values directly to CSV without neutralizing spreadsheet formula prefixes. Values beginning with =, +, -, or @ may be interpreted as formulas when a generated file is opened in spreadsheet software.

CSV quoting does not reliably prevent formula evaluation because spreadsheet applications commonly evaluate quoted fields after parsing them. An attacker able to influence source construction data could therefore place formula content in fields such as task names, resource names, cost descriptions, or comments. The cleaning routine strips whitespace but does not identify or escape formulas, so the payload can survive reading, cleaning, merging, splitting, and exporting.

Attack Path

  1. An attacker supplies or modifies a construction CSV containing a value such as `=HYPERLINK("https://attacker.example", ...[truncated 1031 chars]
Remediation
View remediation

Remediation Suggestions

  • Sanitize string cells before any spreadsheet-oriented CSV export.
  • Prefix values whose first non-whitespace character is =, +, -, or @ with an apostrophe or another application-approved neutralization character.
  • Apply sanitization consistently in both split_csv and export_csv.
  • Consider treating tab, carriage-return, and line-feed prefixes as dangerous because spreadsheet parsing behavior varies.
  • Keep raw export behavior disabled by default. If exact value preservation is required, expose it as an explicit option with a security warning.
  • Add automated tests covering dangerous prefixes, quoted formulas, leading whitespace, embedded newlines, and values imported from merged files.
  • Document that CSV files intended for spreadsheet use must not be trusted merely because fields are quoted.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:161
Finding

Untrusted CSV Values Used to Construct Output File Paths

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:161-174
Vulnerability Type: Path traversal and unsafe file creation
Risk Level: Medium

Vulnerable Code

python
def split_csv(self, df: pd.DataFrame,
              group_column: str,
              output_dir: str) -> List[str]:
    """Split CSV by column values."""
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    files = []
    for value in df[group_column].unique():
        subset = df[df[group_column] == value]
        filename = f"{group_column}_{value}.csv"
        filepath = output_path / filename
        subset.to_csv(filepath, index=False)
        files.append(str(filepath))

    return files

Technical Analysis

The method interpolates both group_column and each CSV-derived value directly into a filename. It does not reject path separators, traversal components, reserved names, control characters, or other unsafe filename content. It also does not resolve the resulting path and verify that it remains below output_dir.

The group_column parameter provides the most direct traversal primitive because it appears at the beginning of filename. If a DataFrame contains a column whose name includes traversal components and that name is selected for splitting, the resulting path may escape the intended directory. Crafted values can also introduce nested path components; successful traversal through values may depend on the existence of matching intermediate directories because the fixed column-name prefix precedes the injected content.

Existing files are overwritten by default when DataFrame.to_csv opens the destination. Consequently, a successfully escaped path can affect any file writable by the process.

Attack Path

  1. An attacker supplies a CSV with a crafted column name and grouping values containing path separators or traversal components.
  2. The crafted column is passe ...[truncated 1128 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not use raw column names or cell values as filesystem path components.
  • Normalize each component to a conservative allowlist such as ASCII letters, digits, underscores, and hyphens.
  • Reject /, \, . and .. path components, control characters, drive prefixes, absolute paths, and platform-reserved filenames.
  • Generate output names from stable identifiers or hashes and maintain a separate mapping to original group values.
  • Resolve both the output directory and candidate destination, then verify with Path.is_relative_to() or an equivalent containment check that the destination remains within the resolved output directory.
  • Refuse to overwrite existing files by default, or use collision-resistant names and exclusive file creation.
  • Define behavior for null values, excessively long values, and multiple values that normalize to the same filename.
  • Add tests for POSIX traversal, Windows separators and drive paths, absolute paths, Unicode separator lookalikes, reserved device names, and filename collisions.
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest focuses on handling CSV exports via detection, parsing, and cleaning messy data, which implies primarily ingesting and transforming CSV content. The implementation goes beyond that by splitting data into multiple files and creating directories, introducing file-generation behavior not stated in the description.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The stated purpose emphasizes reading construction-software CSV exports, detecting delimiters/encodings, and cleaning messy data. The code additionally provides a general CSV export capability that writes output files, which is broader than the declared read/clean scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The instructions materially expand the skill from CSV handling into general construction project task assistance, and explicitly accept multiple unrelated input formats. This creates scope drift: an agent may attempt actions or analyses outside the reviewed CSV-cleaning capability, increasing the chance of unsafe behavior, misuse of undocumented methods in SKILL.md, or processing of unintended data sources.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file embeds code that creates an output directory and writes one CSV per group value via to_csv, which affects user data on disk. While the behavior is part of the feature, the surrounding skill documentation does not include any explicit warning or note that running this operation will create files in the specified directory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The export_csv method performs a file write using df.to_csv(file_path, ...), which can modify or overwrite files depending on the path provided. The markdown examples and description present export behavior but do not clearly warn users that this operation writes files to the filesystem.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.