CVE-2026-107218 is a medium-severity (CVSS 5.3) CWE-129 vulnerability in github.com/xuri/excelize/v2. A fix is available for github.com/xuri/excelize/v2 — see the affected versions and patch details below.
Excelize: RIGHT() on supplementary-plane text slices with a negative index and panics
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-107218.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
CVE-2026-107218 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 394,415 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
github.com/xuri/excelize/v2Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.
Description
leftRight (calc.go:14236) tests the length with countUTF16String, which counts a rune above U+FFFF as 2. The RIGHT branch on 14241 then slices []rune(text) at utf8.RuneCountInString(text)-numChars, which counts it as 1. For text with N such runes the two measures are 2N and N, so any numChars between them passes the guard and gives a negative index. The numChars < 0 check at 14216 does not help, since the value that gets through is positive.
What makes it worth reporting is AutoFitColWidth, which evaluates formulas without looking like it does, so normalising an uploaded sheet is enough to reach it. One scoping correction to my own wording there: AutoFitColWidth was added in v2.11.0 and does not exist at v2.10.1, so on v2.10.1 the only reachable path is an explicit CalcCellValue.
A 6,077-byte file containing two U+1D7D9 characters in A1 and RIGHT(A1,3) in B1 was created and then opened in a separate program without recovery enabled:
v2.9.1 ok
v2.10.0 ok
v2.10.1 panic: slice bounds out of range [-1:]
v2.11.0 panic: slice bounds out of range [-1:]
So it is a regression, not an old defect. Commit a880146 (2026-01-16) moved the guard to countUTF16String and left the slice on the rune index, and git tag --contains gives v2.10.1 and v2.11.0 only.
RIGHT only. RIGHTB reaches the same function but takes the byte branch at 14225, which is internally consistent, and I probed MID and MIDB from 1 to 5 with no panic. It is the same negative-index family as GHSA-fx5j-qcqg-grpf and GHSA-48hm-4h8j-58fg, though those are shared-string lookups in the reader rather than a unit mismatch in the formula library.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐹Go | github.com/xuri/excelize/v2 | ≥ 2.10.1&&< 2.11.1-0.20260908032718-ecd99d761fe0 | 2.11.1-0.20260908032718-ecd99d761fe0go get github.com/xuri/excelize/v2@v2.11.1-0.20260908032718-ecd99d761fe0 |
Affected Products
excelizeexcelizeDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/xuri/excelize/v2, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update github.com/xuri/excelize/v2 to 2.11.1-0.20260908032718-ecd99d761fe0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-107218 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
Frequently Asked Questions
Is CVE-2026-107218 in your dependencies?
Find it across Go, including transitive dependencies.