T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/run_warehouse_reports.py:97
- Finding
- CSV Formula Injection in Missing-Products Report## Vulnerability Details **File Location**: `scripts/run_warehouse_reports.py`, lines 97–98 **Vulnerability Type**: CSV formula injection and improper CSV encoding **Risk Level**: Medium ### Vulnerable Code ```python for r in rows: f.write(",".join(str(x) for x in r) + "\n") ``` ### Technical Analysis The report generator writes database-controlled `sku`, `name`, `warehouse`, and `reorder_level` values directly into `missing_products.csv`. It neither neutralizes spreadsheet formula prefixes nor uses a standards-compliant CSV encoder. If a text field begins with `=`, `+`, `-`, or `@`, spreadsheet software may interpret it as a formula when a user opens the generated report. Depending on the spreadsheet application and its security configuration, a formula could display deceptive links, initiate external requests, disclose information, or invoke other application-specific functionality. The direct string concatenation also fails to escape commas, double quotes, carriage returns, and newlines. Crafted product values can therefore alter the report structure, inject additional cells or records, and misrepresent warehouse data. Exploitation requires an attacker to control or influence relevant values in the input SQLite database and for a user to open the resulting CSV in spreadsheet software. The Python process itself does not evaluate the injected formula. ### Attack Path 1. An attacker obtains the ability to insert or modify a zero-stock product in the input SQLite database. 2. The attacker sets a selected text field, such as `name`, to a formula-like value—for example, `=HYPERLINK("https://attacker.example","Open report")`. 3. A user invokes `run_warehouse_reports.py` against the affected database. 4. `missing_products_csv()` selects the malicious record and writes its fields verbatim to `missing_products.csv`. 5. The user opens the generated file in spreadsheet software. 6. The spreadsheet interprets the attacker-controlled cell as a formula. The ...[truncated 729 chars]
- Remediation
- ## Remediation Suggestions 1. Use Python’s `csv` module instead of constructing CSV records through string concatenation: ```python import csv def neutralize_spreadsheet_formula(value): text = "" if value is None else str(value) if text.lstrip().startswith(("=", "+", "-", "@")): return "'" + text return text with open(out, "w", encoding="utf-8", newline="") as f: writer = csv.writer(f) writer.writerow(["sku", "name", "warehouse", "reorder_level"]) for row in rows: writer.writerow([neutralize_spreadsheet_formula(value) for value in row]) ``` 2. Define an explicit policy for fields expected to be numeric. Validate and serialize them as numeric values rather than accepting arbitrary text. 3. Neutralize formula markers after accounting for leading spaces, tabs, carriage returns, and other characters that spreadsheet applications may ignore before formula evaluation. 4. Add tests covering values containing formula prefixes, commas, double quotes, carriage returns, and embedded newlines. 5. Treat the SQLite database as untrusted input when it can be supplied or modified by external users. 6. Where formula support is unnecessary, consider generating a non-formula-capable format or importing all generated columns explicitly as text.
