CVE-2026-107219: Excelize: Unbounded spinCount in agile decryption burns CPU during OpenFile

Published Oct 7, 2026
·
Updated

Excelize is a Go language library for reading and writing Microsoft Excel spreadsheets. From 2.3.1 to 2.11.0, agile decryption accepts an attacker-controlled spinCount and performs that many password-key derivation iterations before verifier validation. OpenFile reaches agileDecrypt, which passes the unbounded spinCount to convertPasswdToKey before password verification. When a crafted OLE encrypted-workbook header supplies an excessive spinCount and the file is opened, the key-derivation loop performs unbounded attacker-selected work and cannot be cancelled, allowing an attacker to consume a CPU core for an attacker-controlled duration. No fixed version is available as of this review.

Other sources

Opening a file whose first eight bytes are the OLE magic number sends excelize down the decryption path whether or not the caller set a password, or supports encrypted workbooks at all. openReaderAt (excelize.go:198-215) branches on the header alone, and agileDecrypt calls convertPasswdToKey before the verifier hash is checked, so the key-derivation loop runs spinCount times regardless.

spinCount (crypt.go:98) is a plain int filled by a bare xml.Unmarshal of the file's own EncryptionInfo stream. Nothing bounds it.

A 3072-byte file with spinCount 100000000 makes OpenFile take 58.65s on v2.11.0 with default options, then return zip: not a valid zip file. It is linear at about 0.6 microseconds per iteration and the attacker picks the number, so 1e9 is roughly ten minutes. Nothing on the path takes a context.Context, so the caller cannot cancel it; in an HTTP handler the write timeout returns a response while the goroutine keeps spinning. Memory stays flat at 24 MB, so nothing reclaims it either.

v2.5.0 spinCount=10000000 5.307s v2.9.1 spinCount=10000000 5.444s v2.11.0 spinCount=10000000 7.529s v2.11.0 spinCount=100000000 58.654s

The loop arrived with crypt.go in v2.3.1 and is unchanged through v2.11.0.

Excel and LibreOffice write spinCount 100000, which costs 61ms here, so a ceiling well above the legitimate value would cost real files nothing.

This is availability only, and it is not a vulnerability for a program that only opens files its own operator produced.

— GitHub

Affected Software

2 affected componentsFixes available
go/github.com/xuri/excelize/v2>=2.3.1<=2.11.0
go/github.com/xuri/excelize/v2>=2.3.1<2.11.1-0.20260906004932-2badfcd5841d
2.11.1-0.20260906004932-2badfcd5841d

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade go/github.com/xuri/excelize/v2 to a version that resolves this vulnerability.

    Fixed in 2.11.1-0.20260906004932-2badfcd5841d

Event History

Oct 7, 2026
CVE Published
via MITRE·06:33 PM
Data Sourced
via MITRE·06:33 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·07:17 PM
DescriptionSeverityWeakness
Advisory Published
via GitHub·08:23 PM
Data Sourced
via GitHub·08:23 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Who is exposed to this issue?

Applications using github.com/xuri/excelize/v2 versions 2.3.1 through 2.11.0 are exposed if they call OpenFile on attacker-controlled or otherwise untrusted encrypted Excel workbook files.

2

What must an attacker do to trigger the CPU exhaustion?

An attacker needs to provide a crafted OLE encrypted-workbook header containing an excessive spinCount and cause the application to open the file. No authentication or user interaction is required according to the supplied vector.

3

Does the password need to be valid for exploitation?

No. The attacker-controlled spinCount is used for password-key derivation before verifier validation, so the expensive loop runs before the password is verified.

4

What can be done while no fixed version is available?

Avoid opening untrusted encrypted workbooks with affected versions. Where processing is necessary, isolate workbook handling and apply resource controls because the key-derivation work cannot be cancelled.

5

How can I determine whether my application is affected?

Check whether it depends on github.com/xuri/excelize/v2 at a version from 2.3.1 through 2.11.0 and uses OpenFile to process encrypted workbook files. Affected processing may show a CPU core consumed for an attacker-controlled duration while opening a crafted file.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203