T09 · Insecure Skill Coding Practices
- Location
generate_income_statement.py:87- Finding
Spreadsheet Formula Injection Through Untrusted Category Values
- Content
View full analysis
Vulnerability Details
File Location:
generate_income_statement.py, lines 87–91 and 115–119
Vulnerability Type: Spreadsheet formula injection
Risk Level: MediumVulnerable Code
python # Income categories ws.cell(row=row, column=3, value=cat2) ws.cell(row=row, column=5, value=total) row += 1 for cat3, amount in cat3_dict.items(): ws.cell(row=row, column=4, value=cat3) ws.cell(row=row, column=5, value=amount) # Expense categories ws.cell(row=row, column=3, value=cat2) ws.cell(row=row, column=5, value=total) row += 1 for cat3, amount in cat3_dict.items(): ws.cell(row=row, column=4, value=cat3) ws.cell(row=row, column=5, value=amount)The affected values originate directly from the source workbook:
python cat2 = ws_detail.cell(row=row, column=4).value cat3 = ws_detail.cell(row=row, column=5).valueTechnical Analysis
The
cat2andcat3category values are read from an input workbook and written into the generated workbook without validation or formula neutralization. OpenPyXL interprets a string beginning with=as a spreadsheet formula when assigning it as a cell value.Consequently, a malicious source workbook can place formula syntax in either category column. Instead of appearing as a literal category label, that content is stored as an executable spreadsheet formula in the resulting profit statement. Other formula-triggering prefixes, including
+,-, and@, may also be interpreted specially by spreadsheet applications or downstream export workflows.OpenPyXL itself does not execute the injected formula during report generation. Exploitation occurs when the generated workbook is opened or processed by a spreadsheet application that evaluates formulas. The exact consequences therefore depend on the application, platform, security settings, and enabled spreadsheet features.
Attack Path
- An attacker creates or modifies a sou ...[truncated 1691 chars]
- Remediation
View remediation
Remediation Suggestions
Treat all text copied from source workbooks as untrusted data and neutralize formula-leading characters before assigning values to output cells.
-
Introduce a centralized helper that converts input values to safe literal spreadsheet text:
python def safe_excel_text(value): if value is None: return '' text = str(value) if text.startswith(('=', '+', '-', '@', '\t', '\r')): return "'" + text return text -
Apply it to every input-derived textual field:
python ws.cell(row=row, column=3, value=safe_excel_text(cat2)) for cat3, amount in cat3_dict.items(): ws.cell(row=row, column=4, value=safe_excel_text(cat3)) ws.cell(row=row, column=5, value=amount) -
Validate category values against the expected business format. If category names should not begin with formula metacharacters, reject such workbooks or report the affected rows instead of silently accepting them.
-
Keep formula generation restricted to formulas constructed entirely by the application, such as the existing fixed cell-reference totals. Never concatenate untrusted workbook content into formulas.
-
Add regression tests covering values beginning with
=,+,-,@, tab, and carriage return. Reload the generated workbook with OpenPyXL and verify that sanitized category cells have the string data type rather than the formula data type.
-
