T09 · Insecure Skill Coding Practices
- Location
SKILL.md:207- Finding
Excel Formula Injection Through Unsanitized Estimate Fields
- Content
View full analysis
pd.DataFrame: """Export estimate to DataFrame.""" data = [] for item in self.items: data.append({ 'Line': item.line_number, 'WBS': item.wbs_code, 'Description': item.description, 'Qty': item.quantity, 'Unit': item.unit, 'Unit Cost': item.unit_cost, 'Total': item.total_cost, 'Category': item.category.value, 'Notes': item.notes }) return pd.DataFrame(data) def export_to_excel(self, output_path: str) -> str: """Export estimate to Excel.""" totals = self.calculate_total() with pd.ExcelWriter(output_path, engine='openpyxl') as writer: # Cover sheet cover_df = pd.DataFrame([{ 'Project Name': self.project_name, 'Project Number': self.project_number, 'Estimate Date': self.estimate_date, 'Total Items': len(self.items), 'Direct Cost': totals['cost_summary']['direct_cost'], 'Grand Total': totals['grand_total'] }]) cover_df.to_excel(writer, sheet_name='Summary', index=False) # Line items items_df = self.export_to_df() items_df.to_excel(writer, sheet_name='Line Items', index=False) ``` ### Technical Analysis The Skill accepts text fields such as WBS code, description, unit, and notes and stores them without validation or output encoding. `export_to_df()` transfers these values directly into a Pandas DataFrame, and `export_to_excel()` subsequently writes that DataFrame into an XLSX workbook. Spreadsheet applications may interpret cell values beginning with formula control characters—commonly `=`, `+`, `-`, or `@`—as formulas rather than literal text. An attacker able to supply e ...[truncated 2202 chars]- Remediation
View remediation
object: if not isinstance(value, str): return value stripped = value.lstrip() if stripped.startswith(("=", "+", "-", "@")): return "'" + value return value ``` 3. Apply the sanitizer at the final export boundary rather than relying solely on input validation: ```python data.append({ 'Line': item.line_number, 'WBS': sanitize_excel_text(item.wbs_code), 'Description': sanitize_excel_text(item.description), 'Qty': item.quantity, 'Unit': sanitize_excel_text(item.unit), 'Unit Cost': item.unit_cost, 'Total': item.total_cost, 'Category': item.category.value, 'Notes': sanitize_excel_text(item.notes) }) ``` 4. Sanitize the Summary and Markups worksheets as well, because project metadata and markup names may also originate from users. 5. Reject or remove control characters that are invalid or unsafe in spreadsheet cells. 6. Where feasible, use `openpyxl` to set attacker-controlled cells explicitly as string values and verify that the resulting workbook does not store them as formulas. 7. Add regression tests covering: - Values beginning with each formula prefix. - Prefixes preceded by spaces, tabs, carriage returns, or line feeds. - Formula-like values in every exported text field. - Benign numeric and textual values to ensure they remain unchanged. ]]>
