T09 · Insecure Skill Coding Practices
- Location
scripts/inspect_template.py:49- Finding
Unbounded Parsing of Untrusted Spreadsheet Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/inspect_template.py:49, 65, 81-87, 119-124
Vulnerability Type: Uncontrolled Resource Consumption
Risk Level: MediumVulnerable Code
python def detect_header(rows: Iterable[list[str]]) -> tuple[int | None, list[str], list[list[str]]]: buffered = [row for row in rows]python def inspect_csv(path: Path, delimiter: str) -> dict[str, object]: with path.open("r", encoding="utf-8-sig", newline="") as handle: reader = csv.reader(handle, delimiter=delimiter) rows = [[normalize_cell(cell) for cell in row] for row in reader]python def iter_ws_rows(worksheet) -> list[list[str]]: rows: list[list[str]] = [] for row in worksheet.iter_rows(values_only=True): normalized = [normalize_cell(cell) for cell in row] if any(normalized): rows.append(normalized) return rowspython for row_index in range(worksheet.nrows): row = [ normalize_cell(worksheet.cell_value(row_index, col_index)) for col_index in range(worksheet.ncols) ] if any(row): rows.append(row)Technical Analysis
The inspection script accepts user-provided CSV, TSV, XLS, XLSX, and XLSM files but imposes no limits on input size, worksheet count, row count, column count, cell length, or compressed workbook expansion.
Every CSV row is loaded into a list before header detection. Excel paths similarly materialize all non-empty cells from each selected sheet.
detect_header()then creates another list from its input, although it ultimately examines only the first 15 rows and returns at most three sample rows.Consequently, a specially constructed or simply oversized template can cause excessive memory allocation and CPU use. Compressed Office files may amplify the problem when a relatively small archive expands into a very large worksheet representation.
Attack Path
- An attacker creates an oversized CSV or spreadshee ...[truncated 884 chars]
- Remediation
View remediation
Remediation Suggestions
- Reject inputs exceeding a configured byte-size limit before invoking spreadsheet parsers.
- For XLSX and XLSM files, inspect ZIP metadata and enforce limits on entry count, individual uncompressed entry size, total uncompressed size, and compression ratio.
- Limit the number of worksheets, rows, columns, and characters per cell processed.
- Stream CSV and TSV records rather than materializing the complete file. Stop after collecting enough rows for header detection and preview generation.
- Modify workbook inspection to stop after a bounded number of rows because header detection only requires the first 15 candidate rows and three preview rows.
- Avoid redundant buffering in
detect_header()by accepting an already bounded sequence or consuming only the required number of records. - Run parsing in an isolated worker with explicit memory, CPU, and execution-time limits.
- Return a controlled error when any limit is exceeded rather than continuing partial or unbounded processing.
