Go Avro decoder, Denial of Service (CPU Exhaustion), CVE-2023-37475 (medium)

Listen to this Post

How the CVE works:

The Avro decoder reads array/map block counts as zigzag-encoded long values, converted to Go int (64-bit on amd64/arm64). Attackers set block count to math.MaxInt64 (~9.2e18) and terminate the stream with EOF. Vulnerable loops in sliceSkipDecoder.Decode, mapSkipDecoder.Decode, Reader.ReadArrayCB, and Reader.ReadMapCB iterate over block count without checking the reader’s error state. After the first iteration fails (EOF), r.Error != nil, but Decode calls become no-ops that return instantly. The loop continues for the full math.MaxInt64 iterations, pinning a CPU core. Each iteration does no I/O or memory allocation, only loop overhead. On modern hardware, billions of iterations per second are possible, but 9.2e18 iterations exceed any realistic timeout. The process either hangs indefinitely or is killed by OOM or deadline. Remote unauthenticated attackers send a single small payload to exhaust CPU. The fix adds an error check inside the loop and breaks on first failure. No bound on loop length itself; allocation caps (MaxSliceAllocSize, MaxMapAllocSize) provide defense against well-formed huge payloads.

dailycve form:

Platform: Go Avro
Version: <=v2.31.0
Vulnerability: CPU exhaustion
Severity: Medium
date: 2026-05-11

Prediction: Patch available v2.33.0

What Undercode Say:

Analytics:

Check affected module version
go list -m github.com/hamba/avro/v2 | grep -E 'v2.([0-2].|3[bash].)'
Simulate vulnerable pattern (proof-of-concept in Go)
cat > poc.go <<EOF
package main
import ("bytes"; "github.com/hamba/avro/v2")
func main() {
// Payload: MaxInt64 block count + EOF
data := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f}
decoder := avro.NewDecoder(avro.NewPrimitiveSchema(avro.TypeInt, nil), bytes.NewReader(data))
var out interface{}
decoder.Decode(&out) // Pins CPU
}
EOF
go run poc.go
Monitor CPU spike per request
watch -n1 'ps aux | grep avro-decoder | grep -v grep'

Exploit:

Send an Avro binary payload: first byte 0xff (zigzag long start), followed by 8 bytes 0xff, then 0x7f (varint for MaxInt64), then no more data. For array of ints, the decoder reads block count, tries to read first element, hits EOF, then loops MaxInt64-1 times. Single core pinned until process killed.

Protection from this CVE:

Upgrade to github.com/iskorotkov/avro/v2 >= v2.33.0. Or add replace directive: replace github.com/hamba/avro/v2 => github.com/iskorotkov/avro/v2 v2.33.0. Configure caps: cfg := avro.Config{MaxSliceAllocSize: 10000, MaxMapAllocSize: 10000}.Freeze(). Set per-request decode timeouts: ctx, cancel := context.WithTimeout(context.Background(), 1time.Second).

Impact:

Remote unauthenticated denial-of-service: single small payload permanently pins one CPU core per decoder goroutine. If many requests, all cores exhausted, service becomes unresponsive. No memory corruption or RCE, only availability loss. In cloud environments, costs spike from auto-scaling or kill signals.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Previous

ci4ms Pages Module, Stored XSS, Critical

Scroll to Top