T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/reconcile_gst_upi.py:220
- Finding
- Spreadsheet Formula Injection in Generated CSV Reports<![CDATA[ ## Vulnerability Details **File Location**: `scripts/reconcile_gst_upi.py`, lines 220-257 **Vulnerability Type**: CSV/spreadsheet formula injection **Risk Level**: High ### Vulnerable Code ```python with open(recon_csv, "w", encoding="utf-8", newline="") as f: fields = [ "invoice_no", "invoice_date", "customer_name", "invoice_total", "upi_txn_date", "upi_amount", "upi_txn_id", "upi_utr", "match_score", "match_reason", "match_status", ] w = csv.DictWriter(f, fieldnames=fields) w.writeheader() for r in matched: w.writerow(r) with open(gst_csv, "w", encoding="utf-8", newline="") as f: fields = ["invoice_no", "invoice_date", "customer_name", "total_amount", "taxable_value", "gst_amount", "match_status"] w = csv.DictWriter(f, fieldnames=fields) w.writeheader() for g in unreconciled_gst: w.writerow( { "invoice_no": g.invoice_no, "invoice_date": g.invoice_date.isoformat() if g.invoice_date else "", "customer_name": g.customer, "total_amount": g.total_amount, "taxable_value": g.taxable_value, "gst_amount": g.gst_amount, "match_status": "GST_UNMATCHED", } ) with open(upi_csv, "w", encoding="utf-8", newline="") as f: fields = ["txn_date", "amount", "status", "txn_id", "utr", "payer", "note", "match_status"] w = csv.DictWriter(f, fieldnames=fields) w.writeheader() for u in unreconciled_upi: w.writerow( ``` ### Technical Analysis Values originating in untrusted GST and UPI input files—including invoice numbers, customer names, transaction identifiers, UTR values, payer names, and notes—are written directly to CSV output. The implementation does not neutralize strings beginning with spreadsheet formula indicators such as `=`, `+`, `-`, `@`, tab, or carriage ...[truncated 1925 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Introduce a centralized CSV-cell sanitization function and apply it to every string originating from an input file before writing any report: ```python def sanitize_csv_cell(value): if value is None: return "" text = str(value) if text.startswith(("=", "+", "-", "@", "\t", "\r")): return "'" + text return text ``` Additional hardening measures: 1. Sanitize all string fields, including invoice numbers, customer names, transaction IDs, UTR values, payer names, notes, status values, and match reasons. 2. Apply sanitization at the final output boundary so newly added fields are less likely to bypass protection. 3. Document that generated files may contain untrusted financial-statement content. 4. Add regression tests for values beginning with `=`, `+`, `-`, `@`, tab, and carriage return. 5. If exact raw values must be preserved, generate a non-executable format such as JSON alongside a separately sanitized spreadsheet report. ]]>
