T09 · Insecure Skill Coding Practices
Error
- Location
- write_file.py:490
- Finding
- XLSX append mode silently destroys existing spreadsheet data<![CDATA[ ## Vulnerability Details **File Location**: `write_file.py:490-535` **Vulnerability Type**: Destructive data-integrity flaw in archive append handling **Risk Level**: High ### Vulnerable Code ```python def append_to_xlsx(file_path, rows, force=False): """ 追加数据到 Excel 文件(简化实现:读取现有数据,合并后重新创建) Args: file_path: 文件路径 rows: 二维数组,每行数据 force: 是否跳过安全警告确认 Returns: 写入的字节数 """ # 安全检查 is_safe, warnings = check_path_safety(file_path) if warnings: for warning in warnings: print(f"[安全警告] {warning}", file=sys.stderr) if not force: print(f"[操作中止] 检测到潜在安全风险,请使用 --force 参数确认执行", file=sys.stderr) raise PermissionError("安全警告:写入操作被中止") # 读取现有数据 existing_rows = [] with zipfile.ZipFile(file_path, 'r') as zf: try: shared_strings_content = zf.read('xl/sharedStrings.xml').decode('utf-8') # 提取所有字符串 import re matches = re.findall(r'<t>([^<]*)</t>', shared_strings_content) # 读取 worksheet 获取行列结构 worksheet_content = zf.read('xl/worksheets/sheet1.xml').decode('utf-8') # 简单解析:获取行数 row_matches = re.findall(r'<row r="(\d+)"', worksheet_content) if row_matches: max_row = int(max(row_matches)) # 这里简化处理,假设每行有相同列数 # 实际应该更复杂地解析 else: max_row = 0 except: pass # 合并数据并重新创建 all_rows = existing_rows + rows return create_xlsx(file_path, all_rows if all_rows else rows) ``` ### Technical Analysis The function claims to append rows to an existing XLSX document by reading the current workbook and rebuilding it. However, `existing_rows` is initialized as an empty list and is never populated. Although the code extracts shared-string matches and worksheet row numbers, neither result is converted into the existing cell ...[truncated 2102 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not advertise or permit XLSX append mode until existing workbook content can be preserved reliably. 2. Replace regular-expression parsing with a standards-compliant XLSX library such as `openpyxl`, if adding a dependency is acceptable. 3. If standard-library-only operation is required, correctly parse: - Shared and inline strings. - Cell references and types. - Sparse rows and columns. - Multiple worksheets. - XML entities and namespaces. 4. Preserve all ZIP members not intentionally modified, including styles, formulas, relationships, metadata, and additional worksheets. 5. Remove the bare `except`. Catch specific exceptions and abort without modifying the original file when parsing fails. 6. Generate the modified workbook in a temporary file located on the same filesystem. 7. Validate that the temporary output is a readable XLSX archive before replacement. 8. Atomically replace the original only after successful validation. 9. Retain a backup or require explicit confirmation before reconstructing an existing workbook. 10. Add regression tests proving that append mode preserves existing values and workbook components. ]]>
