T09 · Insecure Skill Coding Practices
- Location
mx_xuangu.py:222- Finding
Unneutralized Spreadsheet Formulas in Generated CSV Output
- Content
View full analysis
Vulnerability Details
File Location:
mx_xuangu.py, lines 222–228
Vulnerability Type: CSV formula injection
Risk Level: MediumVulnerable Code
python fieldnames = list(rows[0].keys()) safe_name = safe_filename(query) csv_path = output_dir / f"mx_xuangu_{safe_name}.csv" desc_path = output_dir / f"mx_xuangu_{safe_name}_description.txt" with open(csv_path, "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction="ignore") writer.writeheader() for row in rows: writer.writerow(row)Technical Analysis
The script writes API-provided column names and row values directly to a CSV file. Python's
csvmodule correctly escapes CSV delimiters and quotes, but it does not neutralize spreadsheet formulas.When a cell begins with a formula marker such as
=,+,-, or@—potentially following whitespace—spreadsheet applications may interpret the value as an executable formula rather than plain text. Because the rows and field names are derived from a remote API response, a compromised or attacker-influenced upstream service could place formula payloads in generated output.Attack Path
- An attacker compromises or otherwise gains influence over the stock-screening API response.
- The attacker inserts a formula-prefixed string into a returned column name or data value.
datalist_to_rowsor the partial-results parser retains that string without spreadsheet-specific neutralization.- The vulnerable code serializes the value unchanged into the generated CSV file.
- A user opens the CSV with a spreadsheet application.
- The application evaluates the cell as a formula.
- Depending on the application, version, security configuration, and payload, the formula may initiate external requests, disclose spreadsheet data, or invoke dangerous application-specific functionality.
Impact Assessment
Successful exploitation requires attacker control or influence ...[truncated 532 chars]
- Remediation
View remediation
Remediation Suggestions
Neutralize all spreadsheet-sensitive values before writing headers or rows to CSV:
- Convert each value to text before validation.
- Detect optional leading whitespace followed by
=,+,-, or@. - Prefix matching values with an apostrophe or use another neutralization strategy verified against all supported spreadsheet applications.
- Apply the protection to both field names and row values.
- Preserve an unmodified representation only in formats that do not execute formulas, such as JSON.
- Add regression tests for values such as
=1+1,+SUM(A1:A2),-1+2,@SUM(A1:A2), and whitespace-prefixed variants. - Document that generated files contain remotely sourced data and should be treated as untrusted.
For example:
python FORMULA_PREFIX = re.compile(r"^\s*[=+\-@]") def neutralize_csv_cell(value: Any) -> str: text = "" if value is None else str(value) if FORMULA_PREFIX.match(text): return "'" + text return textUse the function to sanitize every header and cell immediately before CSV serialization.
