T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/build_matrix.py:14
- Finding
- CSV Formula Injection in Generated Literature Matrices## Vulnerability Details **File Location**: `scripts/build_matrix.py`, lines 14–15 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```python for row in rows: w.writerow({k: row.get(k, "") for k in fields}) ``` ### Technical Analysis The script reads paper records from a caller-selected JSON file and writes each field directly into a CSV file without neutralizing spreadsheet formula syntax. Python's `csv.DictWriter` correctly quotes and escapes CSV structure, but CSV quoting does not prevent spreadsheet applications from interpreting cell values as formulas. An attacker-controlled value whose first significant character is `=`, `+`, `-`, or `@` may be evaluated when the resulting file is opened in software such as Microsoft Excel or LibreOffice Calc. For example, a record could contain: ```json { "citation": "=HYPERLINK(\"https://attacker.example\",\"Open source\")", "problem": "Example research problem" } ``` The formula would be preserved in the generated CSV rather than treated strictly as inert text. ### Attack Path 1. An attacker supplies or influences a JSON literature record processed by the Skill. 2. The attacker places spreadsheet formula syntax in any supported field, such as `citation`, `problem`, `method`, `data`, `metric`, `key_result`, `limitation`, or `gap`. 3. The script loads the record and writes the malicious value unchanged to the output CSV. 4. A victim opens the generated literature matrix in a spreadsheet application. 5. The application interprets the value as a formula. 6. Depending on the formula, spreadsheet application, configuration, and user interaction, the attacker may present deceptive links, trigger external-resource requests, or attempt application-specific data disclosure. ### Impact Assessment The script itself does not grant command execution, elevated privileges, or additional filesystem permissions. The impact occurs in the security context of the user who opens t ...[truncated 606 chars]
- Remediation
- ## Remediation Suggestions Treat all values written to CSV as untrusted spreadsheet input. 1. Convert values to strings and inspect the first non-whitespace character. 2. Neutralize values beginning with `=`, `+`, `-`, or `@`, commonly by prefixing an apostrophe. 3. Apply sanitization to every user-controlled field. 4. Document that the output is intended to contain text rather than formulas. 5. Add regression tests covering formula-prefixed values, leading whitespace, tabs, newlines, and non-string JSON values. Example hardening: ```python DANGEROUS_PREFIXES = ("=", "+", "-", "@") def sanitize_csv_cell(value): if value is None: return "" value = str(value) if value.lstrip().startswith(DANGEROUS_PREFIXES): return "'" + value return value for row in rows: w.writerow({ key: sanitize_csv_cell(row.get(key, "")) for key in fields }) ``` If preserving exact source text is required, consider generating a format with explicit text cell types, such as an XLSX workbook created with cells configured as strings, while still validating formula-like values.
