Every CVE Search/ Get API key

CVE-2026-107214

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks

7.5 HighFix available

Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.3.1 to 2.11.0, the decryption dispatch performs insufficient structural and parameter validation before standard and agile decryptors slice, index, allocate, and divide using attacker-controlled values. Decrypt passes attacker-controlled EncryptionInfo and EncryptedPackage data into standardDecrypt or agileDecrypt before validating the structures used by those routines. When a malformed OLE compound file with a version-valid EncryptionInfo stream is opened or passed to Decrypt, nine malformed-input classes reach unrecovered Go runtime panics instead of the documented error path, allowing an attacker to terminate the calling process. 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

0.24%Unchanged since Oct 8, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.5

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks

Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.3.1 to 2.11.0, the decryption dispatch performs insufficient structural and parameter validation before standard and agile decryptors slice, index, allocate, and divide using attacker-controlled values. Decrypt passes attacker-controlled EncryptionInfo and EncryptedPackage data into standardDecrypt or agileDecrypt before validating the structures used by those routines. When a malformed OLE compound file with a version-valid EncryptionInfo stream is opened or passed to Decrypt, nine malformed-input classes reach unrecovered Go runtime panics instead of the documented error path, allowing an attacker to terminate the calling process. No fixed version is available as of this review.

Record
CVE-2026-107214
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248
Updated
2026-11-02
EUVDEUVD-2026-94531 7.5

Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.3.1 to 2.11.0, the decryption dispatch performs insufficient structural and parameter validation before standard and agile decryptors slice, index, allocate, and divide using attacker-controlled values. Decrypt passes attacker-controlled EncryptionInfo and EncryptedPackage data into standardDecrypt or agileDecrypt before validating the structures used by those routines. When a malformed OLE compound file with a version-valid EncryptionInfo stream is opened or passed to Decrypt, nine malformed-input classes reach unrecovered Go runtime panics instead of the documented error path, allowing an attacker to terminate the calling process. No fixed version is available as of this review.

Record
EUVD-2026-94531
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-2j4c-ffch-9f23 7.5

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks

Summary

Any file whose first 8 bytes are the OLE compound-file signature (D0 CF 11 E0 A1 B1 1A E1) is routed by OpenFile/OpenReader/OpenBytes → openReaderAt → Decrypt. The version dispatch only guarantees len(EncryptionInfo) >= 4 before handing attacker-controlled EncryptionInfo/EncryptedPackage buffers to standardDecrypt/agileDecrypt, and no callee validates structure. Malformed but version-valid content therefore fails as an unrecovered runtime panic instead of an error, terminating the calling process.

Details

All panic classes below were execution-confirmed against pristine master (ecd99d761fe0, 2026-09-08). excelize.go:211-213 maps Decrypt errors to ErrWorkbookFileFormat, but panics bypass that path and kill the process.

| # | Malformed input | Panic | Site | |---|---|---|---| | 1 | standard, len(EncryptionInfo) 4–11 | slice bounds [:12] | crypt.go:238 | | 2 | standard, attacker-controlled headerSize uint32 | slice bounds [12:12+headerSize] / fixed-offset header reads | crypt.go:238-249 | | 3 | standard, verifier remainder < 72 (AES) / 60 (RC4) bytes | slice bounds in standardEncryptionVerifier | crypt.go:282-295 | | 4 | standard, header.KeySize = 0xFFFFFFFF | slice bounds [:536870911] with capacity 48 | crypt.go:321 | | 5 | standard, EncryptedPackage stream missing/short | slice bounds [8:0] | crypt.go:268 | | 6 | agile, len(EncryptionInfo) 4–7 | slice bounds [8:4] | crypt.go:407 | | 7 | agile, valid XML without <keyEncryptors> | index out of range [0] with length 0 | crypt.go:416, 433 | | 8 | agile, saltValue decoded length ≠ AES block | cipher.NewCBCDecrypter: IV length must equal block size | crypt.go:425 → 512 | | 9 | any, keyData blockSize="0" | integer divide by zero | crypt.go:539 |

Note the asymmetry pinpointing the missing constraint: the agile path already checks len(EncryptedPackage) >= 8 (crypt.go:520-523) but the standard path does not (#5). Existing tests only cover the error paths (short <4 bytes → ErrUnknownEncryptMechanism, bad XML, base64 errors), never these panic paths.

PoC

Standalone programs (public API only, inputs built in memory) were provided to the maintainer by email: 1-decrypt-panic builds seven malformed CFB containers and shows each panic escaping the public Decrypt API plus one end-to-end OpenReader crash. All cases print PANIC on master and BLOCKED with the proposed patch. A regression guard proves legitimate decryption is unaffected: a workbook encrypted with the package's own Encrypt() still opens through the same code path.

(A separate advisory covers the unbounded/negative allocation in extractPart.)

Impact

Any service that calls OpenFile/OpenReader/OpenBytes on untrusted input (upload processing, mail scanning, spreadsheet conversion) can be killed remotely and without authentication by a file of ~100 bytes to ~3 KB. No password is required — panics occur during structural/parameter handling before successful decryption. Site variety means filtering one pattern does not help.

Proposed fix

A recover() boundary in Decrypt mapping any panic to ErrWorkbookFileFormat (restores the documented error-routing contract; legitimate standard/agile decryption unaffected). A complete patch has been provided to the maintainer; per-site length validation is recommended as defense in depth.

Record
GHSA-2j4c-ffch-9f23
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248
Updated
2026-11-02
NVD 7.5

Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.3.1 to 2.11.0, the decryption dispatch performs insufficient structural and parameter validation before standard and agile decryptors slice, index, allocate, and divide using attacker-controlled values. Decrypt passes attacker-controlled EncryptionInfo and EncryptedPackage data into standardDecrypt or agileDecrypt before validating the structures used by those routines. When a malformed OLE compound file with a version-valid EncryptionInfo stream is opened or passed to Decrypt, nine malformed-input classes reach unrecovered Go runtime panics instead of the documented error path, allowing an attacker to terminate the calling process. No fixed version is available as of this review.

Record
CVE-2026-107214
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248
Updated
2026-11-02
OSV 7.5

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks

Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.3.1 to 2.11.0, the decryption dispatch performs insufficient structural and parameter validation before standard and agile decryptors slice, index, allocate, and divide using attacker-controlled values. Decrypt passes attacker-controlled EncryptionInfo and EncryptedPackage data into standardDecrypt or agileDecrypt before validating the structures used by those routines. When a malformed OLE compound file with a version-valid EncryptionInfo stream is opened or passed to Decrypt, nine malformed-input classes reach unrecovered Go runtime panics instead of the documented error path, allowing an attacker to terminate the calling process. No fixed version is available as of this review.

Record
CVE-2026-107214
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248
Updated
2026-11-02
OSVGHSA-2j4c-ffch-9f23 7.5

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks

Summary

Any file whose first 8 bytes are the OLE compound-file signature (D0 CF 11 E0 A1 B1 1A E1) is routed by OpenFile/OpenReader/OpenBytes → openReaderAt → Decrypt. The version dispatch only guarantees len(EncryptionInfo) >= 4 before handing attacker-controlled EncryptionInfo/EncryptedPackage buffers to standardDecrypt/agileDecrypt, and no callee validates structure. Malformed but version-valid content therefore fails as an unrecovered runtime panic instead of an error, terminating the calling process.

Details

All panic classes below were execution-confirmed against pristine master (ecd99d761fe0, 2026-09-08). excelize.go:211-213 maps Decrypt errors to ErrWorkbookFileFormat, but panics bypass that path and kill the process.

| # | Malformed input | Panic | Site | |---|---|---|---| | 1 | standard, len(EncryptionInfo) 4–11 | slice bounds [:12] | crypt.go:238 | | 2 | standard, attacker-controlled headerSize uint32 | slice bounds [12:12+headerSize] / fixed-offset header reads | crypt.go:238-249 | | 3 | standard, verifier remainder < 72 (AES) / 60 (RC4) bytes | slice bounds in standardEncryptionVerifier | crypt.go:282-295 | | 4 | standard, header.KeySize = 0xFFFFFFFF | slice bounds [:536870911] with capacity 48 | crypt.go:321 | | 5 | standard, EncryptedPackage stream missing/short | slice bounds [8:0] | crypt.go:268 | | 6 | agile, len(EncryptionInfo) 4–7 | slice bounds [8:4] | crypt.go:407 | | 7 | agile, valid XML without <keyEncryptors> | index out of range [0] with length 0 | crypt.go:416, 433 | | 8 | agile, saltValue decoded length ≠ AES block | cipher.NewCBCDecrypter: IV length must equal block size | crypt.go:425 → 512 | | 9 | any, keyData blockSize="0" | integer divide by zero | crypt.go:539 |

Note the asymmetry pinpointing the missing constraint: the agile path already checks len(EncryptedPackage) >= 8 (crypt.go:520-523) but the standard path does not (#5). Existing tests only cover the error paths (short <4 bytes → ErrUnknownEncryptMechanism, bad XML, base64 errors), never these panic paths.

PoC

Standalone programs (public API only, inputs built in memory) were provided to the maintainer by email: 1-decrypt-panic builds seven malformed CFB containers and shows each panic escaping the public Decrypt API plus one end-to-end OpenReader crash. All cases print PANIC on master and BLOCKED with the proposed patch. A regression guard proves legitimate decryption is unaffected: a workbook encrypted with the package's own Encrypt() still opens through the same code path.

(A separate advisory covers the unbounded/negative allocation in extractPart.)

Impact

Any service that calls OpenFile/OpenReader/OpenBytes on untrusted input (upload processing, mail scanning, spreadsheet conversion) can be killed remotely and without authentication by a file of ~100 bytes to ~3 KB. No password is required — panics occur during structural/parameter handling before successful decryption. Site variety means filtering one pattern does not help.

Proposed fix

A recover() boundary in Decrypt mapping any panic to ErrWorkbookFileFormat (restores the documented error-routing contract; legitimate standard/agile decryption unaffected). A complete patch has been provided to the maintainer; per-site length validation is recommended as defense in depth.

Record
GHSA-2j4c-ffch-9f23
CVSS 3.1
7.5 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weakness
CWE-248
Updated
2026-11-02
OSVGO-2026-6684 No score

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks in github.com/xuri/excelize

Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks in github.com/xuri/excelize

Record
GO-2026-6684
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
github.com/xuri/excelize/v2
Go
2.3.1 up to 2.11.1-0.20260915055537-22f76f9acb94
2.11.1-0.20260915055537-22f76f9acb94
github.com/360EntSecGroup-Skylar/excelize/v2
Go
2.3.1 and later None known
github.com/xuri/excelize/v2
Go
before 2.11.1-0.20260915055537-22f76f9acb94
2.11.1-0.20260915055537-22f76f9acb94

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-107214 is a high vulnerability (CVSS 7.5) 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.24%, the 15th percentile. Fixed in github.com/xuri/excelize/v2 2.11.1-0.20260915055537-22f76f9acb94.

References

MoveEnter Open