T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/data_clean.py:31
- Finding
- Spreadsheet Formula Injection in Exported CSV and Excel Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/data_clean.py:31-42` **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: Medium ### Vulnerable Code ```python def save_data(df: pd.DataFrame, path: str): p = Path(path) ext = p.suffix.lower() if ext in (".xlsx", ".xls"): df.to_excel(path, index=False) elif ext == ".csv": df.to_csv(path, index=False, encoding="utf-8-sig") elif ext == ".json": df.to_json(path, orient="records", force_ascii=False, indent=2) else: df.to_csv(path, index=False, encoding="utf-8-sig") ``` ### Technical Analysis The application reads user-controlled data as strings and writes it directly to CSV or Excel without neutralizing spreadsheet formula prefixes. Values beginning with characters such as `=`, `+`, `-`, or `@` may be interpreted as formulas when the generated file is opened in spreadsheet software. The cleaning operations do not provide a final output-encoding step that forces untrusted values to be treated as literal text. Consequently, a malicious formula can survive ingestion, cleaning, and export. Whether a particular payload executes depends on the spreadsheet application, its security configuration, and the formula features it supports. Potential payloads include deceptive hyperlinks and formulas that initiate external requests. Legacy or insecure spreadsheet configurations may expose more dangerous functionality. ### Attack Path 1. An attacker places a formula-like value in an input CSV, JSON, or Excel cell. 2. A user invokes the cleaning Skill on that attacker-controlled dataset. 3. The input value passes through the cleaning pipeline without formula neutralization. 4. `save_data` writes the value into the generated CSV or Excel file. 5. The user or another recipient opens the output in spreadsheet software. 6. The spreadsheet application interprets the cell as a formula rather than ordinary text. 7. Depending on application capab ...[truncated 903 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Add a dedicated output-sanitization step for CSV and spreadsheet exports: 1. Inspect every string value before exporting it to CSV or Excel. 2. Treat cells beginning with `=`, `+`, `-`, or `@` as potentially dangerous. Also account for leading whitespace, tabs, carriage returns, and other characters that spreadsheet applications may ignore before evaluating a formula. 3. Prefix dangerous values with an apostrophe or otherwise force the destination cell type to text. 4. Apply protection after all cleaning and transformation steps so later processing cannot reintroduce unsafe values. 5. Use an Excel writer that explicitly sets untrusted cells to text where feasible. 6. Keep JSON output unchanged unless it will subsequently be imported into spreadsheet software. 7. Add regression tests covering every formula prefix, leading whitespace, tabs, Unicode whitespace, and ordinary negative numeric values. 8. Document whether formula neutralization is enabled and provide an explicit opt-out only for trusted data workflows. The sanitizer should distinguish legitimate numeric negative values from untrusted string formulas to avoid unnecessarily changing valid data. ]]>
