Excelize: a row whose earlier cell has a higher column reference than its last cell panics index out of range on almost every worksheet read API
🔗 CVE IDs covered (1)
📋 Description
Affected versions and vulnerable location
- Confirmed at
ae2113b(current HEAD). - Sink:
rows.go:967ws.SheetData.Row[rowIdx].C[colNum-1] = *colDatainsidecheckRow. checkRowcomputeslastColfrom the column of the last cell in document order (rows.go:940), allocatestargetListof that length, then re-scatters every source cell intoC[colNum-1].
Root cause
The slice is sized from the last cell's column, but cells are not required to be column-sorted in the XML. A cell that appears earlier in the row but references a higher column than the last cell has colNum-1 >= len(targetList), so the assignment writes out of range. MaxColumns/TotalRows do not help, every individual column is valid; the bug is the ordering assumption, not magnitude.
Attacker model and reachability
Any service that opens an untrusted spreadsheet and calls a worksheet API that goes through workSheetReader -> checkRow (excelize.go:332): GetCellValue, GetCellFormula, CalcCellValue, GetMergeCells, SetCellValue, and essentially every non-streaming worksheet call. (The streaming GetRows/Rows() SAX path does not trigger it.) Unauthenticated, deterministic, unrecovered panic -> process crash.
Proof of concept (executed)
Crafted xl/worksheets/sheet1.xml with a row whose cells are out of column order and whose earlier cell exceeds the last cell's column:
<row r="1"><c r="D1"><v>4</v></c><c r="C1"><v>3</v></c></row>
GetCellValue("Sheet1","A1") (via getCellStringFunc -> workSheetReader -> checkRow) panicked index out of range [3] with length 3 at rows.go:967.
Confirming grep:
rg -n "func checkRow|lastCol|Row\[rowIdx\].C\[colNum-1\]" rows.go
Suggested fix
Size targetList from the maximum cell column in the row (not the last cell in document order), or bounds-check colNum-1 against len(targetList) and grow the slice as needed before the assignment.
🎯 Affected products1
- go/github.com/xuri/excelize/v2:>= 2.0.0, < 2.11.1-0.20260816084418-46a5eb289448