{"schema":"threatline.record/2","record":{"id":"CVE-2026-107217","aliases":["GHSA-c85p-xxjj-2r75"],"summary":"Excelize ColumnNameToNumber: int64 overflow yields an out-of-domain coordinate with nil error, causing negative slice index panic on r=\"0\" rows","details":"### Summary\n\n`ColumnNameToNumber` (lib.go:220-237) accumulates the bijective base-26 value of a column name in an int64 with only an upper-bound check (`col > MaxColumns`) applied after the loop and no overflow detection. A 14-letter column name whose true value is 3·2⁶⁴ — e.g. **`VGWQHXLSDVIKWV`** — wraps to `col = 0` and passes the guard, so `CellNameToCoordinates(\"VGWQHXLSDVIKWV1\")` returns `(col=0, row=1, err=nil)`.\n\nWhen normalizing a `r=\"0\"` row, `checkSheetR0` (excelize.go:417-443, called from `checkSheet` at excelize.go:405) runs its `checkRow` closure with `col = 0`: `colIdx := col - 1` becomes **-1**, and `sheetData.Row[rowIdx].C[-1]` (excelize.go:424) raises an unrecovered `panic: runtime error: index out of range [-1]`, killing the host process.\n\n### Details\n\n- The row side of the same coordinate gate is enforced (`checkRowNum` at excelize.go:342-350 bounds `r` before the `make([]xlsxRow, row)` allocation; this includes the fix for GHSA-h69g-9hx6-f3v4 / CVE-2026-54063, present in the audited commit). The **column** side is not: `checkSheet`/`lastRowNum`/`checkSheetR0` treat `err == nil` from `CellNameToCoordinates` as proof of an in-domain coordinate (excelize.go:356, :438), which is unsound because of the wrap-around above.\n- The same unsound gate also feeds `ws.SheetData.Row[rowIdx].C[colNum-1]` in `xlsxWorksheet.checkRow` (rows.go:969): a row combining a valid large column (e.g. `XFD1`) with an overflowed column panics identically.\n- Reachable from any `workSheetReader`-based API on an attacker-supplied worksheet: `GetCellValue`, `GetCellFormula`, `SetCellValue`, `GetMergeCells`, `GetSheetDimension`, `GetColWidth`, `AddTable`, etc.\n- Probe on pristine master: `ColumnNameToNumber(\"VGWQHXLSDVIKWV\")` returns `(0, nil)`.\n- This is a distinct root cause from GHSA-h69g-9hx6-f3v4 (row-index allocation): different mechanism (int64 wrap-around → negative index, not oversized allocation), different sink, different fix.\n\n### PoC\n\nA standalone program (public API only) was provided to the maintainer by email (`3-column-overflow`): it builds a workbook in memory whose `xl/worksheets/sheet1.xml` contains `<sheetData><row r=\"0\"><c r=\"VGWQHXLSDVIKWV1\" t=\"inlineStr\"><is><t>pwn</t></is></c></row></sheetData>` (<1 KB of attacker XML), calls `OpenReader`, then `GetCellValue(\"Sheet1\", \"A1\")` → `PANIC_REPRODUCED: runtime error: index out of range [-1]` on master `ecd99d761fe0` (2026-09-08). With the proposed patch the same program prints `NO_PANIC_BLOCKED`.\n\n### Impact\n\nA <1 KB crafted `.xlsx` crashes any service that opens a user-supplied spreadsheet and reads it — upload processing, mail-scanning pipelines, spreadsheet conversion endpoints. Remote, unauthenticated, no privileges.\n\n### Proposed fix\n\nBound the accumulated value inside the loop: check `col > MaxColumns` after each digit. Every digit is at least 1, so any name whose true value exceeds MaxColumns crosses the bound inside the loop, before the accumulation can wrap or overflow — this provably covers all cases, including wraps that would land back inside `[1, MaxColumns]`. A complete patch has been provided to the maintainer.","categories":["Libraries & packages"],"product":"github.com/xuri/excelize/v2","vendor":"qax-os","ecosystem":"go","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c85p-xxjj-2r75","source_modified_at":"2026-10-07T20:23:32Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/xuri/excelize/v2"},"range":">= 2.0.0, < 2.11.1-0.20260910071107-696050fbf14e"},{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c85p-xxjj-2r75","source_modified_at":"2026-10-07T20:23:32Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/xuri/excelize"},"range":">= 1.1.0, <= 1.4.1"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-107217","source_modified_at":"2026-10-08T16:10:25.237Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"excelize","vendor":"qax-os","versions":[{"version":">= 2.0.0, <= 2.11.0","status":"affected"},{"version":">= 1.1.0, <= 1.4.1","status":"affected"}],"defaultStatus":null},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c85p-xxjj-2r75","source_modified_at":"2026-10-07T20:30:05.831565732Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"github.com/xuri/excelize/v2","ecosystem":"Go","purl":"pkg:golang/github.com/xuri/excelize/v2"},"ranges":[{"type":"SEMVER","events":[{"introduced":"2.0.0"},{"fixed":"2.11.1-0.20260910071107-696050fbf14e"}]}],"versions":[]},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c85p-xxjj-2r75","source_modified_at":"2026-10-07T20:30:05.831565732Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"github.com/xuri/excelize","ecosystem":"Go","purl":"pkg:golang/github.com/xuri/excelize"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.1.0"},{"last_affected":"1.4.1"}]}],"versions":[]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-c85p-xxjj-2r75","source_modified_at":"2026-10-07T20:23:32Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"go","name":"github.com/xuri/excelize/v2"},"version":"2.11.1-0.20260910071107-696050fbf14e"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-c85p-xxjj-2r75","source_modified_at":"2026-10-07T20:30:05.831565732Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"github.com/xuri/excelize/v2","ecosystem":"Go","purl":"pkg:golang/github.com/xuri/excelize/v2"},"version":"2.11.1-0.20260910071107-696050fbf14e"}],"cvss":7.5,"severity":"High","kev":{"listed":false},"epss":{"probability":0.00338,"percentile":0.26068,"score_date":"2026-10-23"},"published_at":"2026-10-07T18:26:55.998Z","modified_at":"2026-10-08T16:10:25.237Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-c85p-xxjj-2r75","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-07T20:23:32Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-107217","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-08T16:10:25.237Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-c85p-xxjj-2r75","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-10-07T20:30:05.831565732Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-107217","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/qax-os/excelize/security/advisories/GHSA-c85p-xxjj-2r75","tags":["exploit"]},{"source":"CVE List","url":"https://github.com/qax-os/excelize/pull/2394","tags":["x_refsource_MISC"]},{"source":"CVE List","url":"https://github.com/qax-os/excelize/commit/696050fbf14e74e96a58eef2b16aaf72f381a6a8","tags":["x_refsource_MISC"]},{"url":"https://github.com/advisories/GHSA-c85p-xxjj-2r75","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"yes","technical_impact":"partial","assessed_at":"2026-10-08T16:10:06.103316Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-10-08T16:10:25.237Z","content_hash":"be95551fef47e299406276c425745bc9f069bc05ff8c8b477636ff47f3bec690"}}
