GHSA-2j4c-ffch-9f23

Suggest an improvement
Source
https://github.com/advisories/GHSA-2j4c-ffch-9f23
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-2j4c-ffch-9f23/GHSA-2j4c-ffch-9f23.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-2j4c-ffch-9f23
Aliases
Published
2026-10-08T16:31:32Z
Modified
2026-10-08T16:45:08Z
Severity
  • 7.5 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CVSS Calculator
Summary
Excelize Decrypt: unrecoverable panics on malformed OLE/CFB encrypted workbooks
Details

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.

Database specific
{
    "cwe_ids": [
        "CWE-248"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-08T16:31:32Z",
    "nvd_published_at": "2026-10-07T18:17:19Z",
    "severity": "HIGH"
}
References

Affected packages

Go / github.com/xuri/excelize/v2

Package

Name
github.com/xuri/excelize/v2
View open source insights on deps.dev
Purl
pkg:golang/github.com/xuri/excelize/v2

Affected ranges

Type
SEMVER
Events
Introduced
2.3.1
Fixed
2.11.1-0.20260915055537-22f76f9acb94

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-2j4c-ffch-9f23/GHSA-2j4c-ffch-9f23.json"