GHSA-8mcq-6wmr-jrjv

Suggest an improvement
Source
https://github.com/advisories/GHSA-8mcq-6wmr-jrjv
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-8mcq-6wmr-jrjv/GHSA-8mcq-6wmr-jrjv.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-8mcq-6wmr-jrjv
Aliases
Published
2026-10-07T20:23:08Z
Modified
2026-10-07T20:30:05Z
Severity
  • 6.5 (Medium) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H CVSS Calculator
Summary
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
Details

Affected versions and vulnerable location

  • Confirmed at ae2113b (current HEAD).
  • Sink: rows.go:967 ws.SheetData.Row[rowIdx].C[colNum-1] = *colData inside checkRow.
  • checkRow computes lastCol from the column of the last cell in document order (rows.go:940), allocates targetList of that length, then re-scatters every source cell into C[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.

Database specific
{
    "cwe_ids": [
        "CWE-787"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-07T20:23:08Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
}
References

Affected packages

Go / github.com/xuri/excelize/v2

Package

Name
github.com/xuri/excelize/v2
View open source insights on deps.dev
Purl
pkg:golang/github.com/xuri/excelize/v2

Affected ranges

Type
SEMVER
Events
Introduced
2.0.0
Fixed
2.11.1-0.20260816084418-46a5eb289448

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-8mcq-6wmr-jrjv/GHSA-8mcq-6wmr-jrjv.json"