T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_company_report.py:497
- Finding
- Domestic report permits spreadsheet formula injection from RSS content## Vulnerability Details **File Location**: `scripts/generate_company_report.py:497-500` **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: High ### Vulnerable Code ```python for row in merged_rows: worksheet.append([row.get(header, "") for header in headers]) ``` ### Technical Analysis The report writer inserts externally sourced RSS fields directly into XLSX cells. These fields include the title, article content, source, timestamp, and link. No neutralization is applied when a value begins with a spreadsheet formula marker such as `=`, `+`, `-`, or `@`. Spreadsheet software may interpret such values as formulas rather than text. Depending on the software and its security settings, a formula can initiate external network requests, expose report data through attacker-controlled URLs, present deceptive hyperlinks, or invoke dangerous legacy spreadsheet functionality. ### Attack Path 1. An attacker publishes an RSS item containing a formula payload in its title, content, source, or link. 2. The configured feed collector stores the malicious value in a JSONL data file. 3. `generate_company_report.py` matches the item to a monitored company. 4. The value is passed unchanged to `worksheet.append`. 5. A user opens `reports/company_mentions.xlsx`. 6. The spreadsheet application evaluates or presents the injected formula according to its security configuration. ### Impact Assessment Exploitation does not directly grant Python-process privileges. It targets the user opening the generated workbook and can compromise report integrity, cause unintended outbound requests, disclose information included in formula arguments, or potentially trigger spreadsheet-specific code-execution features in vulnerable or permissively configured clients.
- Remediation
- ## Remediation Suggestions - Treat every feed-derived value as untrusted before writing it to XLSX. - Prefix values beginning with `=`, `+`, `-`, or `@` with a single quote. - Explicitly assign sanitized values as string cells rather than relying on automatic type detection. - Apply the same sanitization to existing workbook rows before rewriting cumulative reports. - Add tests covering formula-prefixed titles, content, links, source names, and AI-generated fields. Example hardening: ```python def safe_excel_text(value: object) -> str: text = str(value or "") if text.startswith(("=", "+", "-", "@")): return "'" + text return text for row in merged_rows: worksheet.append([safe_excel_text(row.get(header, "")) for header in headers]) ```
