T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/csv_to_excel.py:36
- Finding
- CSV Formula Injection in Generated Excel Workbooks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/csv_to_excel.py`, lines 36-44 and 55-60 **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: Medium ### Vulnerable Code ```python if args.input: path = Path(args.input) if not path.exists(): print(f"File does not exist: {path}", file=sys.stderr) sys.exit(1) df = pd.read_csv(path, encoding=args.encoding, sep=args.sep) sheet_name = args.sheet_name or path.stem if len(sheet_name) > 31: sheet_name = sheet_name[:31] df.to_excel(out, sheet_name=sheet_name, index=False, engine="openpyxl") ``` ```python with pd.ExcelWriter(out, engine="openpyxl") as writer: for path in paths: df = pd.read_csv(path, encoding=args.encoding, sep=args.sep) name = path.stem if len(name) > 31: name = name[:31] df.to_excel(writer, sheet_name=name, index=False) ``` ### Technical Analysis The script imports CSV values and writes them directly into an Excel workbook without distinguishing untrusted text from spreadsheet formulas. Values beginning with formula-significant characters such as `=`, `+`, `-`, or `@` may be interpreted as formulas when the resulting workbook is opened in Excel or another compatible spreadsheet application. An attacker who controls any CSV field can therefore place a formula payload in the generated workbook. Depending on the spreadsheet client and its security configuration, such a formula could create deceptive hyperlinks, access external resources, disclose workbook data through supported functions, or abuse legacy formula features. ### Attack Path 1. An attacker creates or modifies a CSV file processed by the Skill. 2. The attacker inserts a value such as: ```text =HYPERLINK("https://attacker.example/login","Open report") ``` 3. A user runs `csv_to_excel.py` against the attacker-controlled CSV. 4. The value is written to the output workbook without neutralization. 5. The use ...[truncated 652 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Treat imported CSV fields as untrusted text before exporting them to a workbook. 1. Detect strings whose first non-whitespace character is `=`, `+`, `-`, or `@`. 2. Prefix such strings with an apostrophe or explicitly set the target Excel cell type and number format to text. 3. Apply the mitigation to column names as well as data values. 4. Provide an explicit opt-in option for users who intentionally need formulas preserved. 5. Add regression tests covering all formula prefixes, leading whitespace, tab characters, and multi-file conversion. For example: ```python FORMULA_PREFIXES = ("=", "+", "-", "@") def neutralize_formula(value): if isinstance(value, str) and value.lstrip().startswith(FORMULA_PREFIXES): return "'" + value return value df = df.map(neutralize_formula) df.columns = [neutralize_formula(str(col)) for col in df.columns] ``` ]]>
