T09 · Insecure Skill Coding Practices
Error
- Location
- tools/employee_manager.py:650
- Finding
- Spreadsheet Formula Injection Through Employee Fields<![CDATA[ ## Vulnerability Details **File Location**: `tools/employee_manager.py:650-672` **Vulnerability Type**: Spreadsheet formula injection **Risk Level**: High ### Vulnerable Code ```python for attrName, defaultHeader in fieldOrder: # Find the corresponding column mappedColumn = self._columnMapping.get(attrName) targetColumn = mappedColumn if mappedColumn else defaultHeader # Find the column index if targetColumn in self._headerRow: colIdx = self._headerRow.index(targetColumn) + 1 else: # Use the default order when the column is unavailable colIdx = fieldOrder.index((attrName, defaultHeader)) + 1 value = getattr(emp, attrName, "") if isinstance(value, str) and not value: value = None elif isinstance(value, float) and value == 0: value = None ws.cell(row=rowIdx, column=colIdx, value=value) ``` The validation performed before saving employee records does not reject or neutralize formula-leading strings: ```python def addEmployee(self, emp: Employee) -> Tuple[bool, str]: # Validation isValid, errors = emp.validate() if not isValid: return False, f"Employee validation failed: {'; '.join(errors)}" # Check employee-number uniqueness if emp.empNo in self.employees: return False, f"Employee number already exists: {emp.empNo}" if not emp.status: emp.status = "probation" emp._isNew = True self.employees[emp.empNo] = emp ``` ### Technical Analysis Employee properties are passed directly to `openpyxl` worksheet cells. A string beginning with `=` is interpreted as a formula rather than ordinary text. Other spreadsheet clients may also interpret strings beginning with `+`, `-`, or `@` as formulas or formula-like expressions. The employee validation routine checks required values and selected phone, email, identity-card, and date formats. It does not sanitize free-form fields such as employee name, department, position, rep ...[truncated 1680 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Create a centralized spreadsheet-output sanitizer and use it for every untrusted string: ```python def sanitize_excel_text(value): if isinstance(value, str) and value.startswith(("=", "+", "-", "@")): return "'" + value return value ``` 2. Apply the sanitizer before every workbook write: ```python value = sanitize_excel_text(value) ws.cell(row=rowIdx, column=colIdx, value=value) ``` 3. Force untrusted textual cells to use a text format where appropriate: ```python cell = ws.cell(row=rowIdx, column=colIdx) cell.number_format = "@" cell.value = sanitize_excel_text(value) ``` 4. Apply equivalent protection to: - Employee fields. - Department fields. - Custom and extra fields. - Workbook headers. - Attendance data. - Payroll and report exports. 5. Add tests covering values beginning with `=`, `+`, `-`, and `@`, including values preceded by whitespace or control characters. 6. Do not rely solely on input validation. Sanitize at the final spreadsheet-output boundary so imported data and values created by other APIs receive the same protection. ]]>
