CVE-2026-62160
Daptin: ParseAcceptLanguage `_` separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware
Daptin is a GraphQL/JSON-API headless CMS. Prior to 0.12.26, the global LanguageMiddleware in server/language.go passes the raw Accept-Language header from LanguageMiddlewareFunc through GetLanguagePreference to golang.org/x/text/language.ParseAcceptLanguage without a size or shape filter. The guard for CVE-2022-32149 counts hyphens but not underscores, even though the internal parser normalizes underscores to hyphens. Long lists of underscore-separated language subtags longer than eight characters bypass the guard. These subtags fail the len <= 8 length check in golang.org/x/text/internal/language/parse.go, causing repeated gobble operations to move the entire remaining buffer through runtime.memmove. With many invalid subtags, this repeated buffer movement takes quadratic work. Unauthenticated requests to the public landing page or /api can consume disproportionate CPU, with a 256 KiB header already causing seconds of processing and larger input permitted by the default 1 MiB header ceiling. resource.CheckErr also logs the entire invalid header, amplifying cost, while normal successful HTTP responses can conceal the denial-of-service traffic. Repeated requests can saturate server CPU. This issue is fixed in version 0.12.26.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.7
Daptin: ParseAcceptLanguage `_` separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware
Daptin is a GraphQL/JSON-API headless CMS. Prior to 0.12.26, the global LanguageMiddleware in server/language.go passes the raw Accept-Language header from LanguageMiddlewareFunc through GetLanguagePreference to golang.org/x/text/language.ParseAcceptLanguage without a size or shape filter. The guard for CVE-2022-32149 counts hyphens but not underscores, even though the internal parser normalizes underscores to hyphens. Long lists of underscore-separated language subtags longer than eight characters bypass the guard. These subtags fail the len <= 8 length check in golang.org/x/text/internal/language/parse.go, causing repeated gobble operations to move the entire remaining buffer through runtime.memmove. With many invalid subtags, this repeated buffer movement takes quadratic work. Unauthenticated requests to the public landing page or /api can consume disproportionate CPU, with a 256 KiB header already causing seconds of processing and larger input permitted by the default 1 MiB header ceiling. resource.CheckErr also logs the entire invalid header, amplifying cost, while normal successful HTTP responses can conceal the denial-of-service traffic. Repeated requests can saturate server CPU. This issue is fixed in version 0.12.26.
- Record
CVE-2026-62160- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-02
EUVDEUVD-2026-114281
8.7
Daptin is a GraphQL/JSON-API headless CMS. Prior to 0.12.26, the global LanguageMiddleware in server/language.go passes the raw Accept-Language header from LanguageMiddlewareFunc through GetLanguagePreference to golang.org/x/text/language.ParseAcceptLanguage without a size or shape filter. The guard for CVE-2022-32149 counts hyphens but not underscores, even though the internal parser normalizes underscores to hyphens. Long lists of underscore-separated language subtags longer than eight characters bypass the guard. These subtags fail the len <= 8 length check in golang.org/x/text/internal/language/parse.go, causing repeated gobble operations to move the entire remaining buffer through runtime.memmove. With many invalid subtags, this repeated buffer movement takes quadratic work. Unauthenticated requests to the public landing page or /api can consume disproportionate CPU, with a 256 KiB header already causing seconds of processing and larger input permitted by the default 1 MiB header ceiling. resource.CheckErr also logs the entire invalid header, amplifying cost, while normal successful HTTP responses can conceal the denial-of-service traffic. Repeated requests can saturate server CPU. This issue is fixed in version 0.12.26.
- Record
EUVD-2026-114281- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-rhj7-vh3v-mcq6
8.7
Daptin: ParseAcceptLanguage `_` separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware
Summary
Daptin's LanguageMiddleware (registered as a global gin middleware) calls golang.org/x/text/language.ParseAcceptLanguage on the raw Accept-Language header of every HTTP request without imposing any size or shape filter. The underlying parser has quadratic-time behaviour on long lists of malformed language tags. The CVE-2022-32149 guard that golang.org/x/text added in v0.3.8 caps the number of - characters in the input at 1000, but it does not cap _ characters even though the parser's internal scanner aliases _ to - before parsing. A single unauthenticated GET request with an Accept-Language header built out of _ separators (only 256 KiB, not even the 1 MiB ceiling) consumes about 27 seconds of server CPU on the host running Daptin. A 1 MiB payload exceeds the 2-minute test client timeout. A single attacker on a 1 Mbit/s uplink can pin an entire Daptin host with one request every 30 seconds.
Affected versions
github.com/daptin/daptin v0.12.15 and (per code inspection of master) all earlier 0.12.x versions that wire LanguageMiddleware on the global gin router without imposing their own size limit on Accept-Language. Verified on:
- the official release binary
daptin-linux-amd64v0.12.15 built into a Docker image from the project's ownDockerfile(E2E below) masterat commitb021ac4ae1f72b7401e851fcf883bc970303c794by readingserver/language.go(the middleware is unchanged)
Privilege required
Unauthenticated. The middleware is registered on the global gin router that serves both the public landing page and the unauthenticated /api style endpoints. Anyone who can reach the HTTP listener (port 8080 by default) is in scope.
Vulnerable code
server/language.go (blob SHA b021ac4ae1f72b7401e851fcf883bc970303c794):
func (lm *LanguageMiddleware) LanguageMiddlewareFunc(c *gin.Context) {
pref := GetLanguagePreference(c.GetHeader("Accept-Language"), lm.defaultLanguage)
c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), "language_preference", pref))
}
func GetLanguagePreference(header string, defaultLanguage string) []string {
preferredLanguage := header
if preferredLanguage == "" || preferredLanguage == "undefined" || preferredLanguage == "null" {
preferredLanguage = defaultLanguage
}
languageTags, _, err := language.ParseAcceptLanguage(preferredLanguage)
resource.CheckErr(err, "Failed to parse Accept-Language header [%v]", preferredLanguage)
pref := make([]string, 0)
prefMap := make(map[string]bool)
if len(languageTags) == 1 && languageTags[0].String() == defaultLanguage {
// single tag matches default — skip
} else {
for _, tag := range languageTags {
base, conf := tag.Base()
if conf == 0 {
continue
}
if prefMap[base.String()] == true {
continue
}
prefMap[base.String()] = true
pref = append(pref, base.String())
}
}
return pref
}
c.GetHeader("Accept-Language") is the unfiltered HTTP header. Go's default net/http MaxHeaderBytes is 1 << 20 = 1 MiB and Daptin does not override it, so the parser is allowed to receive up to a megabyte of attacker-controlled data.
The resource.CheckErr call on the error path also formats the entire input string into a log line (Failed to parse Accept-Language header [%v]), amplifying the cost on attacker-supplied 256 KiB-1 MiB payloads.
CVE-2022-32149 hardened ParseAcceptLanguage by counting - characters and rejecting inputs with more than 1000 of them. The guard does not count _ characters even though the scanner converts _ to - at parse time (golang.org/x/text/internal/language/parse.go). A 256 KiB…
- Record
GHSA-rhj7-vh3v-mcq6- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-02
NVD
8.7
Daptin is a GraphQL/JSON-API headless CMS. Prior to 0.12.26, the global LanguageMiddleware in server/language.go passes the raw Accept-Language header from LanguageMiddlewareFunc through GetLanguagePreference to golang.org/x/text/language.ParseAcceptLanguage without a size or shape filter. The guard for CVE-2022-32149 counts hyphens but not underscores, even though the internal parser normalizes underscores to hyphens. Long lists of underscore-separated language subtags longer than eight characters bypass the guard. These subtags fail the len <= 8 length check in golang.org/x/text/internal/language/parse.go, causing repeated gobble operations to move the entire remaining buffer through runtime.memmove. With many invalid subtags, this repeated buffer movement takes quadratic work. Unauthenticated requests to the public landing page or /api can consume disproportionate CPU, with a 256 KiB header already causing seconds of processing and larger input permitted by the default 1 MiB header ceiling. resource.CheckErr also logs the entire invalid header, amplifying cost, while normal successful HTTP responses can conceal the denial-of-service traffic. Repeated requests can saturate server CPU. This issue is fixed in version 0.12.26.
- Record
CVE-2026-62160- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-02
OSV
8.7
Daptin: ParseAcceptLanguage `_` separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware
Daptin is a GraphQL/JSON-API headless CMS. Prior to 0.12.26, the global LanguageMiddleware in server/language.go passes the raw Accept-Language header from LanguageMiddlewareFunc through GetLanguagePreference to golang.org/x/text/language.ParseAcceptLanguage without a size or shape filter. The guard for CVE-2022-32149 counts hyphens but not underscores, even though the internal parser normalizes underscores to hyphens. Long lists of underscore-separated language subtags longer than eight characters bypass the guard. These subtags fail the len <= 8 length check in golang.org/x/text/internal/language/parse.go, causing repeated gobble operations to move the entire remaining buffer through runtime.memmove. With many invalid subtags, this repeated buffer movement takes quadratic work. Unauthenticated requests to the public landing page or /api can consume disproportionate CPU, with a 256 KiB header already causing seconds of processing and larger input permitted by the default 1 MiB header ceiling. resource.CheckErr also logs the entire invalid header, amplifying cost, while normal successful HTTP responses can conceal the denial-of-service traffic. Repeated requests can saturate server CPU. This issue is fixed in version 0.12.26.
- Record
CVE-2026-62160- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-06
OSVGHSA-rhj7-vh3v-mcq6
8.7
Daptin: ParseAcceptLanguage `_` separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware
Summary
Daptin's LanguageMiddleware (registered as a global gin middleware) calls golang.org/x/text/language.ParseAcceptLanguage on the raw Accept-Language header of every HTTP request without imposing any size or shape filter. The underlying parser has quadratic-time behaviour on long lists of malformed language tags. The CVE-2022-32149 guard that golang.org/x/text added in v0.3.8 caps the number of - characters in the input at 1000, but it does not cap _ characters even though the parser's internal scanner aliases _ to - before parsing. A single unauthenticated GET request with an Accept-Language header built out of _ separators (only 256 KiB, not even the 1 MiB ceiling) consumes about 27 seconds of server CPU on the host running Daptin. A 1 MiB payload exceeds the 2-minute test client timeout. A single attacker on a 1 Mbit/s uplink can pin an entire Daptin host with one request every 30 seconds.
Affected versions
github.com/daptin/daptin v0.12.15 and (per code inspection of master) all earlier 0.12.x versions that wire LanguageMiddleware on the global gin router without imposing their own size limit on Accept-Language. Verified on:
- the official release binary
daptin-linux-amd64v0.12.15 built into a Docker image from the project's ownDockerfile(E2E below) masterat commitb021ac4ae1f72b7401e851fcf883bc970303c794by readingserver/language.go(the middleware is unchanged)
Privilege required
Unauthenticated. The middleware is registered on the global gin router that serves both the public landing page and the unauthenticated /api style endpoints. Anyone who can reach the HTTP listener (port 8080 by default) is in scope.
Vulnerable code
server/language.go (blob SHA b021ac4ae1f72b7401e851fcf883bc970303c794):
func (lm *LanguageMiddleware) LanguageMiddlewareFunc(c *gin.Context) {
pref := GetLanguagePreference(c.GetHeader("Accept-Language"), lm.defaultLanguage)
c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), "language_preference", pref))
}
func GetLanguagePreference(header string, defaultLanguage string) []string {
preferredLanguage := header
if preferredLanguage == "" || preferredLanguage == "undefined" || preferredLanguage == "null" {
preferredLanguage = defaultLanguage
}
languageTags, _, err := language.ParseAcceptLanguage(preferredLanguage)
resource.CheckErr(err, "Failed to parse Accept-Language header [%v]", preferredLanguage)
pref := make([]string, 0)
prefMap := make(map[string]bool)
if len(languageTags) == 1 && languageTags[0].String() == defaultLanguage {
// single tag matches default — skip
} else {
for _, tag := range languageTags {
base, conf := tag.Base()
if conf == 0 {
continue
}
if prefMap[base.String()] == true {
continue
}
prefMap[base.String()] = true
pref = append(pref, base.String())
}
}
return pref
}
c.GetHeader("Accept-Language") is the unfiltered HTTP header. Go's default net/http MaxHeaderBytes is 1 << 20 = 1 MiB and Daptin does not override it, so the parser is allowed to receive up to a megabyte of attacker-controlled data.
The resource.CheckErr call on the error path also formats the entire input string into a log line (Failed to parse Accept-Language header [%v]), amplifying the cost on attacker-supplied 256 KiB-1 MiB payloads.
CVE-2022-32149 hardened ParseAcceptLanguage by counting - characters and rejecting inputs with more than 1000 of them. The guard does not count _ characters even though the scanner converts _ to - at parse time (golang.org/x/text/internal/language/parse.go). A 256 KiB…
- Record
GHSA-rhj7-vh3v-mcq6- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-06
OSVGO-2026-6890 No score
Daptin: ParseAcceptLanguage `_` separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware in github.com/daptin/daptin
Daptin: ParseAcceptLanguage _ separator bypass enables >250x CPU amplification via Accept-Language header in LanguageMiddleware in github.com/daptin/daptin
- Record
GO-2026-6890- Updated
- 2026-11-06
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/daptin/daptinGo |
through 0.12.15 | None known |
github.com/daptin/daptinGo |
All versions | None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-62160 is a high vulnerability (CVSS 8.7) in Daptin, published October 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.42%, the 36th percentile. No source names a fixed version.
References
github.com/daptin/daptin/security/advisories/GHSA-rhj7-vh3v-mcq6
github.com/daptin/daptin/commit/2d70950979b51eb6c8b4234dd50558b608ad2ffe
github.com/advisories/GHSA-rhj7-vh3v-mcq6
github.com/CVEProject/cvelistV5/tree/main/cves/2026/62xxx/CVE-2026-62160.json
nvd.nist.gov/vuln/detail/CVE-2026-62160
github.com/daptin/daptin
Left out here: the rest of 2 source descriptions. The JSON record has them.