When we think of web application attacks, we often picture SQL injections or XSS. But sometimes, the mildly boring headers we ignore can open up a nasty vulnerability. That’s the story behind CVE-2022-32149, a Denial of Service (DoS) bug in Go’s standard library. Let’s break down how this issue works, what makes it tick, and how attackers can easily abuse it.
What is CVE-2022-32149?
In short: An attacker can make your Go server super slow (and even take it down) just by sending a painfully crafted Accept-Language header. This tricks Go's ParseAcceptLanguage function into eating up CPU and memory, choking your server.
Safe: Go 1.18.5, 1.17.13, and later
(Always check the official advisory for up-to-date info.)
Why Does This Happen?
Go’s language parsing is done by golang.org/x/text/language.ParseAcceptLanguage. This function is meant to figure out which languages a client prefers. However, if you send it headers with a massive number of comma-delimited entries (like hundreds or thousands), it bogs down.
Here’s a simplified snippet that shows where trouble begins
import "golang.org/x/text/language"
header := r.Header.Get("Accept-Language")
tags, q, err := language.ParseAcceptLanguage(header)
if err != nil {
// handle error
}
If header is long and complex, ParseAcceptLanguage will take forever, exhausting CPU resources.
Real Exploit: Simple and Devastating
An attacker doesn’t need special skills. All it takes is a single HTTP request with a monstrous Accept-Language header.
Sample Exploit (in Bash, using curl)
curl -H "Accept-Language: $(python3 -c 'print(",".join(["en"]*10000))')" http://targetsite.com/
Here, we generate a header with 10,000 language tags. When the server tries to process this with ParseAcceptLanguage, it grinds to a halt.
You can try this (on your own test server!) and watch the CPU spike using top or htop.
High CPU Usage: Processing the header is computationally expensive.
- Denial of Service: If requests are sent in parallel, your server will choke, queueing up requests and eventually freezing.
How Was It Fixed?
The fix is in CL 418075. It limits how much work ParseAcceptLanguage will do and ignores excessive entries.
Always update to the latest Go version to be safe!
Mitigation & Best Practices
- Update Go and x/text: Patch to Go 1.18.5, 1.17.13, or later versions.
- Limit Header Size: At your reverse proxy (nginx, Caddy, etc.), set a strict limit on header length.
Validate Input: If you must parse headers, check their length and entry count first.
header := r.Header.Get("Accept-Language")
if len(header) > 2048 {
http.Error(w, "Request header too large", http.StatusRequestHeaderFieldsTooLarge)
return
}
References
- Go CVE-2022-32149 Security Advisory
- Go Issue 52988
- CL 418075 – The Patch
- golang.org/x/text/language code
Final Thoughts
CVE-2022-32149 shows that even simple HTTP headers can be turned against us if the code isn’t careful. If you’re running any Go web apps, patch now and always be suspicious of anything user-controlled – even language preferences.
Do you use Go in production? Share your thoughts or patching war stories below!
Timeline
Published on: 10/14/2022 15:15:00 UTC
Last modified on: 10/18/2022 17:41:00 UTC