T09 · Insecure Skill Coding Practices
- Location
lib/tax_calc.py:2165- Finding
Spreadsheet Formula Injection in Batch CSV Export
- Content
View full analysis
Vulnerability Details
File Location:
lib/tax_calc.py, lines 2165-2169
Vulnerability Type: CSV/spreadsheet formula injection
Risk Level: MediumVulnerable Code
python for emp in batch_result["员工明细"]: csv += f"{emp['姓名']},{emp['月薪']:.2f},{emp['年终奖']:.2f}," csv += f"{emp['年度税前']:.2f},{emp['月度个税']:.2f}," csv += f"{emp['月度到手']:.2f},{emp['年度个税']:.2f}," csv += f"{emp['年度到手']:.2f}\n"Technical Analysis
The employee name inserted through
emp['姓名']originates from caller-controlled employee data and is concatenated directly into CSV output. The code performs neither standards-compliant CSV quoting nor spreadsheet formula neutralization.If a name begins with a spreadsheet formula marker such as
=,+,-, or@, spreadsheet software may interpret the cell as a formula rather than plain text. For example:text =HYPERLINK("https://attacker.example","Open")Names containing commas, quotation marks, carriage returns, or newlines can also alter the CSV structure and inject additional cells or rows.
Attack Path
- An attacker or untrusted data source supplies an employee record whose
namestarts with a spreadsheet formula marker. batch_calculate_tax()copies the supplied name into the batch result under the employee-name field.generate_batch_excel_data()concatenates that value directly into the first CSV column.- The generated data is saved as a CSV file and opened by an HR or payroll user in spreadsheet software.
- The spreadsheet application may evaluate the attacker-controlled value as a formula.
- The formula may display deceptive links, initiate external resource lookups, or perform other actions allowed by the spreadsheet application and its security configuration.
Impact Assessment
Successful exploitation occurs in the context of the user opening the exported CSV, not with the privileges of the Python calculator itself. The potential scope includes:
- Execution of attacke ...[truncated 650 chars]
- An attacker or untrusted data source supplies an employee record whose
- Remediation
View remediation
Remediation Suggestions
- Generate CSV through Python's
csv.writerrather than manual string concatenation so commas, quotation marks, carriage returns, and newlines are escaped correctly. - Treat every user-controlled textual field as potentially formula-bearing.
- Before writing a text cell, inspect its first non-whitespace character. If it is
=,+,-, or@, prefix the value with an apostrophe or use another neutralization strategy compatible with the intended spreadsheet software. - Preserve the original name separately if exact round-trip fidelity is required, and document any neutralization applied to exported values.
- Open output streams with
newline=""and an explicit encoding such as UTF-8 with BOM when compatibility with common spreadsheet applications is required. - Add regression tests for names containing formula markers, commas, quotation marks, tabs, carriage returns, and newlines.
Example hardening pattern:
python import csv import io def neutralize_spreadsheet_formula(value: object) -> str: text = str(value) if text.lstrip().startswith(("=", "+", "-", "@")): return "'" + text return text output = io.StringIO(newline="") writer = csv.writer(output) writer.writerow([ "Name", "Monthly Salary", "Bonus", "Annual Gross", "Monthly Tax", "Monthly Net", "Annual Tax", "Annual Net", ]) for emp in batch_result["Employee Details"]: writer.writerow([ neutralize_spreadsheet_formula(emp["Name"]), f"{emp['Monthly Salary']:.2f}", f"{emp['Bonus']:.2f}", f"{emp['Annual Gross']:.2f}", f"{emp['Monthly Tax']:.2f}", f"{emp['Monthly Net']:.2f}", f"{emp['Annual Tax']:.2f}", f"{emp['Annual Net']:.2f}", ]) csv_data = output.getvalue()The field names in the example should be adapted to the application's existing result structure.
- Generate CSV through Python's
