GHSA-h69g-9hx6-f3v4: Excelize: Unbounded Row Index Allocation in Worksheet Parser (checkSheet OOM/Panic DoS)
Unbounded Row Index Allocation in Worksheet Parser (checkSheet OOM/Panic DoS)
Summary
The checkSheet() function in github.com/xuri/excelize/v2 uses an attacker-controlled <row r="N"> XML attribute value directly as the length argument to make([]xlsxRow, row) without validating it against the Excel row limit (TotalRows = 1,048,576). A specially crafted XLSX file can trigger two denial-of-service variants: (A) an out-of-memory process kill when r=2147483647 forces a ~16 GB allocation attempt, and (B) a runtime panic via out-of-bounds slice indexing when r=-1. Any service that opens attacker-supplied XLSX files and calls GetCellValue is affected. No authentication is required.
Details
The vulnerable code path is triggered by calling GetCellValue (or any API that internally invokes workSheetReader) on an XLSX file containing a crafted worksheet row element.
Data flow (source → sink):
1. excelize.go:186-193 — OpenReader reads attacker-controlled spreadsheet bytes.
2. excelize.go:216-223 — ZIP reader is created and passed to ReadZipReader.
3. lib.go:43-77 — ZIP entries are read into fileList; worksheet XML is stored by part name.
4. excelize.go:228-229 — XML bytes are stored in f.Pkg.
5. cell.go:71-79 — Public GetCellValue enters the worksheet value-read path.
6. cell.go:1492-1494 — getCellStringFunc calls workSheetReader.
7. excelize.go:313-324 — Worksheet XML is decoded into xlsxWorksheet.
8. xmlWorksheet.go:302-312 — <row r="..."> is deserialized into xlsxRow.R int with no validation (source).
9. excelize.go:357-377 — checkSheet() accumulates the maximum r value; sink: make([]xlsxRow, row) allocates a slice of that size before any bounds check.
Vulnerable code (excelize.go:373-377):
if r.R != 0 && r.R > row {
row = r.R
}
sheetData := xlsxSheetData{Row: make([]xlsxRow, row)} // unbounded allocation
The constant TotalRows = 1048576 is defined in templates.go:190 but is never applied before the make() call in checkSheet(), leaving the allocation fully attacker-cont
Details
Original advisory: https://github.com/advisories/GHSA-h69g-9hx6-f3v4
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-54063 | coverage & exploitation status | NVD · CVE.org |
Same CVEs, other sources
How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.
More from GitHub Security Advisories
- criticalGHSA-g936-7jqj-mwv8: TSDProxy: Internal proxy auth token forwarded to backend services enables management API …2026-07-10
- highGHSA-fpg8-7664-jc5q: melange: Incomplete package integrity verification allows data section substitution2026-07-10
- mediumGHSA-48rx-c7pg-q66r: Excon does not redact additional sensitive/risky headers when following redirects2026-07-10
- highGHSA-h4g2-xfmw-q2c9: Clauster: Non-loopback deployments can serve the dashboard unauthenticated when auth.enab…2026-07-10
- mediumGHSA-rqq5-2gf9-4w4q: Secure Headers: CSP directive injection via sandbox, plugin_types, and report_to when giv…2026-07-10