CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-h69g-9hx6-f3v4: Excelize: Unbounded Row Index Allocation in Worksheet Parser (checkSheet OOM/Panic DoS)

highCVSS 7.5CVE-2026-54063
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

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 7.5
Published
2026-07-10
Last updated
2026-07-10
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-h69g-9hx6-f3v4

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-54063coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories