CVE-2026-107211
Excelize: Unchecked pivot-cache field index in extractPivotTableFields causes unrecoverable panic
Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.8.1 to 2.11.0, separately parsed pivot-table field indices are used to index the pivot-cache field-name slice without bounds checks. extractPivotTableFields uses getPivotCacheFieldsName output while processing GetPivotTables and trusts the dataField fld attribute as an index. When a crafted workbook supplies a pivot-field count mismatch or an out-of-range dataField fld value before GetPivotTables is called, the unchecked index causes a Go slice-bounds panic that escapes the library, allowing an attacker to crash the process or request worker. No fixed version is available as of this review.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
Excelize: Unchecked pivot-cache field index in extractPivotTableFields causes unrecoverable panic
Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.8.1 to 2.11.0, separately parsed pivot-table field indices are used to index the pivot-cache field-name slice without bounds checks. extractPivotTableFields uses getPivotCacheFieldsName output while processing GetPivotTables and trusts the dataField fld attribute as an index. When a crafted workbook supplies a pivot-field count mismatch or an out-of-range dataField fld value before GetPivotTables is called, the unchecked index causes a Go slice-bounds panic that escapes the library, allowing an attacker to crash the process or request worker. No fixed version is available as of this review.
- Record
CVE-2026-107211- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-129
- Updated
- 2026-11-02
EUVDEUVD-2026-94526
8.7
Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.8.1 to 2.11.0, separately parsed pivot-table field indices are used to index the pivot-cache field-name slice without bounds checks. extractPivotTableFields uses getPivotCacheFieldsName output while processing GetPivotTables and trusts the dataField fld attribute as an index. When a crafted workbook supplies a pivot-field count mismatch or an out-of-range dataField fld value before GetPivotTables is called, the unchecked index causes a Go slice-bounds panic that escapes the library, allowing an attacker to crash the process or request worker. No fixed version is available as of this review.
- Record
EUVD-2026-94526- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-mx22-3794-2vpv
8.7
Excelize: Unchecked pivot-cache field index in extractPivotTableFields causes unrecoverable panic
Summary
extractPivotTableFields builds order := pc.getPivotCacheFieldsName() from xl/pivotCache/pivotCacheDefinitionN.xml's <cacheFields> list, then indexes it with values taken from a separately parsed xl/pivotTables/pivotTableN.xml part with zero cross-validation: order[field.Fld] where field.Fld is a raw attacker-controlled int from the <dataField fld="N"> attribute, and order[fieldIdx] where fieldIdx is a loop index over pt.PivotFields.PivotField that need not match the cache's field count. I executed two independent PoCs against the current HEAD: (1) trimmed the pivot cache's <cacheFields> to count=0 while leaving the pivot table's 2 pivotFields untouched -> runtime error: index out of range [0] with length 0 at pivotTable.go:1431; (2) left the 2 cache fields completely intact and only changed one attribute, fld="1" -> fld="99999", in xl/pivotTables/pivotTable1.xml -> runtime error: index out of range [99999] with length 2 at pivotTable.go:1443. Both stack traces confirmed via non-recovered go test runs: extractPivotTableFields -> getPivotTable -> GetPivotTables.
Reachability / who can trigger this
Unauthenticated: any application that opens an untrusted .xlsx containing a pivot table and calls the public File.GetPivotTables(sheet) API. excelize has no recover() anywhere, so this crashes the host process (CLI/worker) or surfaces as an unhandled 500 in a request-scoped-recover HTTP service. Deterministic, single small crafted file, no user interaction beyond the service's normal open-and-read flow.
Proof of Concept / Reproduction
Method:
- Verified source at HEAD (commit e81f0500, 2026-09-27, freshly cloned/up to date;
git statusclean except the new PoC files I added): read pivotTable.go:1425-1454 and confirmed verbatim:order := pc.getPivotCacheFieldsName()(1428), loopfor fieldIdx, field := range pt.PivotFields.PivotFieldindexingorder[fieldIdx]at axisRow/axisCol/axisPage (1431/1434/1437), andData: order[field.Fld](1443) inside thept.DataFields.DataFieldloop -- zero bounds checks anywhere. Confirmed xmlPivotTable.go:271Fld intxml:"fld,attr"`` on xlsxDataField (raw attacker-controlled int, no validation) and the sibling Fld field at line 252. Rango build ./...-- compiles clean. Both citations are accurate. - Found the repo already contained an untracked PoC test file from earlier work (pivot_fld_poc_test.go) implementing this exact finding via a byte-level zip-tamper technique (build a legitimate workbook with excelize's own public AddPivotTable API, then hex-edit one raw XML part inside the saved .xlsx's zip bytes -- not a hypothetical reimplementation, uses the real unmodified excelize package). Did not just trust it: ran it myself with
go test -run 'TestPivotTableDataFieldFldIndexPanic|TestPivotTableDataFieldFldAttributeOutOfRangePanic' -v .and observed real PASS output with exact matching panic strings. - For stronger, independent evidence beyond a recover-wrapped test, I wrote my own standalone non-test Go program from scratch, cmd/pivotcrash/main.go (module github.com/xuri/excelize/v2, go1.27.0 toolchain), that imports the real compiled excelize package (no reimplementation) with two subcommands:
gen/gen-trim(attacker: build a legit pivot-table workbook via the public API, then rezip with one XML part tampered -- either dataField fld="1"->fld="99999", or the pivot cache's <cacheFields count="2"> collapsed to count="0" -- writing the crafted .xlsx to disk) andrun(victim: a fresh OS process that does exactly what any consumer service does --excelize.OpenFile(path)thenf.GetPivotTables("Sheet1")-- with zero recover() anywhere in the file or the call chain). Executed as four separatego runprocess invocations: gen, run, gen-trim, run.
Evidence:
Test run (pre-existing PoC file, re-executed by me, both PASS):
--- PASS: TestPivotTableDataFieldFldIndexPanic (0.00s) logging `CONFIRMED: GetPivotTables panicked ...…
- Record
GHSA-mx22-3794-2vpv- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-129
- Updated
- 2026-11-02
NVD
8.7
Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.8.1 to 2.11.0, separately parsed pivot-table field indices are used to index the pivot-cache field-name slice without bounds checks. extractPivotTableFields uses getPivotCacheFieldsName output while processing GetPivotTables and trusts the dataField fld attribute as an index. When a crafted workbook supplies a pivot-field count mismatch or an out-of-range dataField fld value before GetPivotTables is called, the unchecked index causes a Go slice-bounds panic that escapes the library, allowing an attacker to crash the process or request worker. No fixed version is available as of this review.
- Record
CVE-2026-107211- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-129
- Updated
- 2026-11-02
OSV
8.7
Excelize: Unchecked pivot-cache field index in extractPivotTableFields causes unrecoverable panic
Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.8.1 to 2.11.0, separately parsed pivot-table field indices are used to index the pivot-cache field-name slice without bounds checks. extractPivotTableFields uses getPivotCacheFieldsName output while processing GetPivotTables and trusts the dataField fld attribute as an index. When a crafted workbook supplies a pivot-field count mismatch or an out-of-range dataField fld value before GetPivotTables is called, the unchecked index causes a Go slice-bounds panic that escapes the library, allowing an attacker to crash the process or request worker. No fixed version is available as of this review.
- Record
CVE-2026-107211- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-129
- Updated
- 2026-11-02
OSVGHSA-mx22-3794-2vpv
8.7
Excelize: Unchecked pivot-cache field index in extractPivotTableFields causes unrecoverable panic
Summary
extractPivotTableFields builds order := pc.getPivotCacheFieldsName() from xl/pivotCache/pivotCacheDefinitionN.xml's <cacheFields> list, then indexes it with values taken from a separately parsed xl/pivotTables/pivotTableN.xml part with zero cross-validation: order[field.Fld] where field.Fld is a raw attacker-controlled int from the <dataField fld="N"> attribute, and order[fieldIdx] where fieldIdx is a loop index over pt.PivotFields.PivotField that need not match the cache's field count. I executed two independent PoCs against the current HEAD: (1) trimmed the pivot cache's <cacheFields> to count=0 while leaving the pivot table's 2 pivotFields untouched -> runtime error: index out of range [0] with length 0 at pivotTable.go:1431; (2) left the 2 cache fields completely intact and only changed one attribute, fld="1" -> fld="99999", in xl/pivotTables/pivotTable1.xml -> runtime error: index out of range [99999] with length 2 at pivotTable.go:1443. Both stack traces confirmed via non-recovered go test runs: extractPivotTableFields -> getPivotTable -> GetPivotTables.
Reachability / who can trigger this
Unauthenticated: any application that opens an untrusted .xlsx containing a pivot table and calls the public File.GetPivotTables(sheet) API. excelize has no recover() anywhere, so this crashes the host process (CLI/worker) or surfaces as an unhandled 500 in a request-scoped-recover HTTP service. Deterministic, single small crafted file, no user interaction beyond the service's normal open-and-read flow.
Proof of Concept / Reproduction
Method:
- Verified source at HEAD (commit e81f0500, 2026-09-27, freshly cloned/up to date;
git statusclean except the new PoC files I added): read pivotTable.go:1425-1454 and confirmed verbatim:order := pc.getPivotCacheFieldsName()(1428), loopfor fieldIdx, field := range pt.PivotFields.PivotFieldindexingorder[fieldIdx]at axisRow/axisCol/axisPage (1431/1434/1437), andData: order[field.Fld](1443) inside thept.DataFields.DataFieldloop -- zero bounds checks anywhere. Confirmed xmlPivotTable.go:271Fld intxml:"fld,attr"`` on xlsxDataField (raw attacker-controlled int, no validation) and the sibling Fld field at line 252. Rango build ./...-- compiles clean. Both citations are accurate. - Found the repo already contained an untracked PoC test file from earlier work (pivot_fld_poc_test.go) implementing this exact finding via a byte-level zip-tamper technique (build a legitimate workbook with excelize's own public AddPivotTable API, then hex-edit one raw XML part inside the saved .xlsx's zip bytes -- not a hypothetical reimplementation, uses the real unmodified excelize package). Did not just trust it: ran it myself with
go test -run 'TestPivotTableDataFieldFldIndexPanic|TestPivotTableDataFieldFldAttributeOutOfRangePanic' -v .and observed real PASS output with exact matching panic strings. - For stronger, independent evidence beyond a recover-wrapped test, I wrote my own standalone non-test Go program from scratch, cmd/pivotcrash/main.go (module github.com/xuri/excelize/v2, go1.27.0 toolchain), that imports the real compiled excelize package (no reimplementation) with two subcommands:
gen/gen-trim(attacker: build a legit pivot-table workbook via the public API, then rezip with one XML part tampered -- either dataField fld="1"->fld="99999", or the pivot cache's <cacheFields count="2"> collapsed to count="0" -- writing the crafted .xlsx to disk) andrun(victim: a fresh OS process that does exactly what any consumer service does --excelize.OpenFile(path)thenf.GetPivotTables("Sheet1")-- with zero recover() anywhere in the file or the call chain). Executed as four separatego runprocess invocations: gen, run, gen-trim, run.
Evidence:
Test run (pre-existing PoC file, re-executed by me, both PASS):
--- PASS: TestPivotTableDataFieldFldIndexPanic (0.00s) logging `CONFIRMED: GetPivotTables panicked ...…
- Record
GHSA-mx22-3794-2vpv- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-129
- Updated
- 2026-11-02
OSVGO-2026-6695 No score
Panic via unchecked pivot-cache field index in github.com/xuri/excelize/v2
Panic via unchecked pivot-cache field index in github.com/xuri/excelize/v2
- Record
GO-2026-6695- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/xuri/excelize/v2Go |
2.8.1 up to 2.11.1-0.20261003002531-6258dcebc4e2 | 2.11.1-0.20261003002531-6258dcebc4e2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-107211 is a high vulnerability (CVSS 8.7) in Excelize, published October 7, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.23%, the 14th percentile. Fixed in github.com/xuri/excelize/v2 2.11.1-0.20261003002531-6258dcebc4e2.
References
github.com/qax-os/excelize/security/advisories/GHSA-mx22-3794-2vpv
github.com/qax-os/excelize/pull/2435
github.com/qax-os/excelize/commit/6258dcebc4e2a2aed985c38a08098dfd908521d1
nvd.nist.gov/vuln/detail/CVE-2026-107211
github.com/advisories/GHSA-mx22-3794-2vpv
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107211.json
github.com/qax-os/excelize
Left out here: the rest of 2 source descriptions. The JSON record has them.