CVE-2026-59162 Overview
CVE-2026-59162 is a denial-of-service vulnerability in Excelize, a Go language library for reading and writing Microsoft Excel spreadsheets. Versions prior to 2.11.0 parse shared-string cell values with strconv.Atoi and validate only the upper bound before indexing the shared string slice. An attacker who supplies a crafted XLSX file containing a shared-string cell with the value -1 can trigger sharedStrings[-1], causing a runtime panic when the file is read through GetCellValue or GetRows. The issue is tracked as GHSA-fx5j-qcqg-grpf and fixed in Excelize 2.11.0.
Critical Impact
A malicious XLSX file processed by applications using vulnerable Excelize versions causes an uncaught panic, disrupting service availability for any workflow that parses untrusted spreadsheet input.
Affected Products
- Excelize (github.com/qax-os/excelize) versions prior to 2.11.0
- Go applications and services that parse untrusted XLSX files via Excelize
- Downstream libraries and tools embedding vulnerable Excelize releases
Discovery Timeline
- 2026-07-10 - CVE-2026-59162 published to NVD
- 2026-07-16 - Last updated in NVD database
Technical Details for CVE-2026-59162
Vulnerability Analysis
The defect lies in Excelize's shared string resolution path inside cell.go. When a cell references a shared string, Excelize converts the raw string value to an integer index using strconv.Atoi and then indexes into the d.SI slice. The original code only checked len(d.SI) > xlsxSI, which is satisfied for any negative integer because Go's len returns a non-negative value greater than a negative one. Indexing a Go slice with a negative integer raises a runtime panic that unwinds the goroutine.
The weakness is classified as [CWE-248] Uncaught Exception. Exploitation is unauthenticated and reachable over the network wherever an application exposes XLSX parsing to remote input, such as file upload endpoints, data ingestion pipelines, or report processors. Confidentiality and integrity remain intact; only availability is affected.
Root Cause
Missing lower-bound validation on a signed integer used as a slice index. strconv.Atoi returns a signed int, but the guard only compared against the slice length. Supplying -1 as the shared string reference bypasses the bounds check and reaches the panicking index operation.
Attack Vector
An attacker crafts an XLSX file whose sheet1.xml contains a cell with a shared-string reference of -1. When the target application calls GetCellValue or GetRows on that file, Excelize resolves the reference, converts -1 via strconv.Atoi, passes the upper-bound-only check, and panics on d.SI[-1]. No authentication or user interaction is required beyond delivering the file to the parser.
// Patch from cell.go: enforce both lower and upper bounds before indexing
// Source: https://github.com/qax-os/excelize/commit/93f0b3caed37f21ef5079e3259c6c21dcfe68453
}
d.mu.Lock()
defer d.mu.Unlock()
- if len(d.SI) > xlsxSI {
- return f.formattedValue(&xlsxC{S: c.S, V: d.SI[xlsxSI].String()}, raw, CellTypeSharedString)
+ if xlsxSI < 0 || xlsxSI >= len(d.SI) {
+ return "", newInvalidSharedStringIndex(xlsxSI)
}
+ return f.formattedValue(&xlsxC{S: c.S, V: d.SI[xlsxSI].String()}, raw, CellTypeSharedString)
}
return f.formattedValue(c, raw, CellTypeSharedString)
case "str":
The accompanying error constructor introduced in errors.go surfaces the invalid index instead of panicking:
// Source: https://github.com/qax-os/excelize/commit/93f0b3caed37f21ef5079e3259c6c21dcfe68453
// newInvalidSharedStringIndex defined the error message on receive an invalid
// shared string index.
func newInvalidSharedStringIndex(idx int) error {
return fmt.Errorf("invalid shared string index %d", idx)
}
Detection Methods for CVE-2026-59162
Indicators of Compromise
- XLSX files containing shared-string cell references with negative integer values, such as <c t="s"><v>-1</v></c> in sheet*.xml
- Application crash logs showing runtime error: index out of range [-1] originating from github.com/xuri/excelize or github.com/qax-os/excelize stack frames
- Repeated goroutine panics tied to GetCellValue or GetRows invocations following file uploads
Detection Strategies
- Inventory Go dependencies with go list -m -u all or govulncheck to flag Excelize modules below version 2.11.0.
- Inspect XLSX uploads in transit by unzipping the archive and scanning xl/worksheets/sheet*.xml for shared-string cells whose <v> element parses to a negative integer.
- Correlate web server 5xx spikes with file upload endpoints that invoke Excelize parsing routines.
Monitoring Recommendations
- Alert on process restarts or crash-loop patterns for services that ingest spreadsheets.
- Capture stack traces from Go panics and forward them to centralized logging for pattern matching against Excelize frames.
- Track file upload telemetry, including source IP, filename, and hash, to enable retrospective hunting once a malicious sample is identified.
How to Mitigate CVE-2026-59162
Immediate Actions Required
- Upgrade Excelize to version 2.11.0 or later in all Go modules and rebuild affected binaries.
- Recover any Go binaries shipping vulnerable Excelize versions and redeploy after dependency updates.
- Add input validation at application boundaries to reject XLSX files from untrusted sources until patching is complete.
Patch Information
The fix is delivered in Excelize 2.11.0 via commit 93f0b3caed37f21ef5079e3259c6c21dcfe68453 and pull request qax-os/excelize#2331. Full details are published in the GitHub Security Advisory GHSA-fx5j-qcqg-grpf and the Excelize v2.11.0 release notes. Update go.mod to require github.com/xuri/excelize/v2 v2.11.0 and run go mod tidy.
Workarounds
- Wrap Excelize parsing calls in recover() handlers so panics do not terminate the host process.
- Pre-validate uploaded XLSX files by parsing shared-string references and rejecting any negative index values before invoking GetCellValue or GetRows.
- Isolate spreadsheet parsing in a sandboxed worker process that can be restarted without affecting the primary service.
# Configuration example: update Excelize to the patched release
go get github.com/xuri/excelize/v2@v2.11.0
go mod tidy
govulncheck ./...
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

