T09 · Insecure Skill Coding Practices
- Location
scripts/get_data.py:74- Finding
Spreadsheet Formula Injection in Generated CSV Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/get_data.py, lines 74-83 and 242-281
Vulnerability Type: CSV/spreadsheet formula injection
Risk Level: MediumVulnerable Code:
python def _flatten_value(v: Any) -> str: """ Convert arbitrary cell values to strings. """ if v is None: return "" if isinstance(v, (dict, list)): return json.dumps(v, ensure_ascii=False) return str(v)python fieldnames_set: Dict[str, None] = {} for row in rows: for k in row: fieldnames_set[k] = None priority_fields = ["entity_name", "indicator_name", "indicator_code", "frequency", "Data Source"] fieldnames = [] for field in priority_fields: if field in fieldnames_set: fieldnames.append(field) del fieldnames_set[field] date_fields = [] other_fields = [] for field in fieldnames_set.keys(): if (field.isdigit() and len(field) == 4) or \ (re.match(r'^\d{4}-\d{2}-\d{2}$', field)): date_fields.append(field) else: other_fields.append(field) date_fields.sort(reverse=True) other_fields.sort() fieldnames.extend(other_fields) fieldnames.extend(date_fields) csv_path = output_dir / f"mx_macro_data_{unique_suffix}_{frequency}.csv" 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({k: _flatten_value(v) for k, v in row.items()})Technical Analysis
CSV column names and cell values derived from the remote API response are written without neutralizing spreadsheet formula prefixes.
_flatten_value()converts values to strings but does not protect strings beginning with=,+,-, or@.Spreadsheet applications can interpret such cells as formulas when a generated CSV file is opened. CSV quoting perfor ...[truncated 1696 chars]
- Remediation
View remediation
Remediation Suggestions
- Introduce a dedicated CSV-sanitization function that detects strings whose first non-whitespace character is
=,+,-, or@. - Prefix potentially dangerous values with a single quote or another format-appropriate neutralization character before writing them.
- Apply sanitization to both cell values and remotely derived column names.
- Consider exporting to a format that supports explicit text cell types when files are primarily intended for spreadsheet applications.
- Document that generated files contain untrusted remote data and should not bypass spreadsheet security warnings.
- Add automated tests covering each dangerous prefix, leading whitespace, tabs, carriage returns, nested JSON values, and malicious header names.
- Preserve raw values separately only if required, and do not place unsanitized values into spreadsheet-interpreted cells.
- Introduce a dedicated CSV-sanitization function that detects strings whose first non-whitespace character is
