---
id: "CVE-2026-107222"
page: "https://infrastack.ai/live/CVE-2026-107222"
kind: "vulnerability"
aliases: ["CVE-2026-107222", "GHSA-rxcj-4pj5-74gr", "GO-2026-6682"]
title: "Excelize: GetConditionalFormats indexes conditional-formatting rule sub-elements with no length or nil check"
severity: "medium"
cvss: 6.5
epss: 0.0027
exploited: false
status: "open"
category: "package"
products: [{"name": "github.com/xuri/excelize/v2", "fixed": ["2.11.1-0.20260812075026-be7a16390fa6"], "affected": ">= 2.7.0, < 2.11.1-0.20260812075026-be7a16390fa6", "ecosystem": "go"}, {"name": "excelize", "fixed": [], "affected": ">= 2.7.0, <= 2.11.0", "ecosystem": "vendor"}]
ecosystems: ["go", "vendor"]
tags: ["cwe-129", "cwe-476", "excelize", "go", "package", "spreadsheet-parsing"]
not_affected_if: ["no-untrusted-spreadsheets", "versions-at-or-after-fix", "versions-before-2.7.0"]
published_at: "2026-10-07T19:17:34+00:00"
first_seen_at: "2026-11-06T00:09:03+00:00"
updated_at: "2026-11-06T00:19:08+00:00"
sources: [{"source": "govuln", "url": "https://pkg.go.dev/vuln/GO-2026-6682", "first_seen_at": "2026-11-06T00:09:03+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-107222", "first_seen_at": "2026-11-06T00:19:01+00:00"}, {"source": "ghsa", "url": "https://github.com/advisories/GHSA-rxcj-4pj5-74gr", "first_seen_at": "2026-11-06T00:19:08+00:00"}]
exploit_sources: [{"type": "epss", "score": 0.0027, "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-107222"}]
---

# Excelize: GetConditionalFormats indexes conditional-formatting rule sub-elements with no length or nil check

Link for people: https://infrastack.ai/live/CVE-2026-107222 (this .md is for agents)

The excelize Go library indexes conditional-formatting rule sub-elements without checking their length or nil state, so reading a malformed spreadsheet can panic. The sources do not say whether an attacker can run code or read data from this.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- go:github.com/xuri/excelize/v2 affected >= 2.7.0, < 2.11.1-0.20260812075026-be7a16390fa6 fixed 2.11.1-0.20260812075026-be7a16390fa6
- vendor:excelize affected >= 2.7.0, <= 2.11.0 fixed no fixed version listed

## How to check

- Check whether the project depends on `github.com/xuri/excelize/v2` with `go list -m github.com/xuri/excelize/v2`
- Check whether the version is `2.7.0` or later and below `2.11.1-0.20260812075026-be7a16390fa6`
- Check whether the app calls `GetConditionalFormats` on spreadsheets from untrusted users

## Fix

- `github.com/xuri/excelize/v2` `2.11.1-0.20260812075026-be7a16390fa6`

## Timeline

- 2026-11-06T00:09:03+00:00 govuln https://pkg.go.dev/vuln/GO-2026-6682
- 2026-11-06T00:19:01+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-107222
- 2026-11-06T00:19:08+00:00 ghsa https://github.com/advisories/GHSA-rxcj-4pj5-74gr

## Documents

- [advisory] Vendor advisory: github.com https://github.com/qax-os/excelize/security/advisories/GHSA-rxcj-4pj5-74gr
- [advisory] Maintainer's advisory: api.github.com https://api.github.com/repos/qax-os/excelize/security-advisories/GHSA-rxcj-4pj5-74gr
- [fix] Patch: github.com https://github.com/qax-os/excelize/commit/be7a16390fa69c71d3ca618c741d1a2b5ed362cd
- [fix] Patch: github.com https://github.com/qax-os/excelize/pull/2375

## From the sources

## Summary

`GetConditionalFormats` reads sub-elements of a `<cfRule>` straight out of `xl/worksheets/sheetN.xml` and indexes them without checking length, and in one case without checking for nil. Three rule types are affected: `cellIs`, `dataBar` and `colorScale`. A workbook with a rule that is missing a child a real Excel file would always have panics the call.

## Where it is

All three sinks are in `styles.go`, at the same line numbers in v2.11.0 and on master `d552a7e`. All three are reached from `GetConditionalFormats` through `styles.go:3271`.

`styles.go:3003`, in `extractCondFmtCellIs`:

```go
	format.Value = c.Formula[0]
```

The branch above it handles `len(c.Formula) == 2`; this one is the fallback and does not check that there is a formula at all, so a `cellIs` rule with no `<formula>` child indexes an empty slice.

`styles.go:3132`, in the colorScale extractor:

```go
	values := len(c.ColorScale.Cfvo)
```

`c.ColorScale` is a `*xlsxColorScale` and is nil when the `<cfRule type="colorScale">` element has no `<colorScale>` child. Lines 3148 and 3153 then index `Cfvo[1]` and `Cfvo[2]` in the three-colour branch with no length check either.

`styles.go:3186`, `:3188` and `:3190`, in the dataBar extractor:

```go
		format.MinType = c.DataBar.Cfvo[0].Type
		...
		format.BarColor = "#" + f.getThemeColor(c.DataBar.Color[0])
```

The guard here is `c.DataBar != nil`, which says nothing about the length of `Cfvo` or `Color`, so an empty `<dataBar></dataBar>` element reaches all three.

## Who the attacker is

Anyone who can hand a spreadsheet to a service that opens it and calls `GetConditionalFormats`. No authentication, no user interaction beyond the service doing its normal job, and the file is small.

## Reproduction

Three minimal `.xlsx` files were built, each a real zip with `[Content_Types].xml`, `_rels/.rels`, `xl/workbook.xml`, `xl/_rels/workbook.xml.rels` and one worksheet, opened each with the public `excelize.OpenReader` and called `GetConditionalFormats("Sheet1")`. Nothing internal is touched.

The worksheet fragment for the `cellIs` case, note there is no `<formula>` child:

```xml
<conditionalFormatting sqref="A1"><cfRule type="cellIs" operator="equal" priority="1" dxfId="0"/></conditionalFormatting>
```

for `dataBar`:

```xml
<conditionalFormatting sqref="A1"><cfRule type="dataBar" priority="1"><dataBar></dataBar></cfRule></conditionalFormatting>
```

and for `colorScale`:

```xml
<conditionalFormatting sqref="A1"><cfRule type="colorScale" priority="1"/></conditionalFormatting>
```

Observed against master `d552a7e` on go1.26.5:

```text
cellIs      panic: runtime error: index out of range [0] with length 0
              styles.go:3003
              styles.go:1217
              styles.go:3271

dataBar     panic: runtime error: index out of range [0] with length 0
              styles.go:3186
              styles.go:1262
              styles.go:3271

colorScale  panic: runtime error: invalid memory address or nil pointer dereference
              styles.go:3132
              styles.go:1259
              styles.go:3271
```

One honesty note on impact. These are ordinary Go panics, not fatal errors, so a caller that wraps the call in `recover` survives them.

## Suggested fix

Length-check `c.Formula` before line 3003 and return the rule with an empty value when there is no formula. Nil-check `c.ColorScale` before line 3132 and length-check `ColorScale.Cfvo` before indexing 1 and 2. Length-check `DataBar.Cfvo` and `DataBar.Color` alongside the existing nil check at 3186 to 3190. Skipping the malformed rule rather than erroring would keep `GetConditionalFormats` usable on files that are merely sloppy.

## Affected versions

`github.com/xuri/excelize/v2` up to and including v2.11.0, and master at `d552a7e`. I read the three sinks at tag v2.11.0 and at master and ran the reproducers against master.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
