A AegiFlow
HIGHCVSS 7.1

CVE-2026-56755

Gitea: Denial of Service (CPU & Memory Exhaustion) via O(N^2) String Concatenation in Debian Package Upload

Published
2026-07-21
Modified
2026-07-21
Aliases
GHSA-6hm7-3pwj-22rm
Sources
github-advisory

Summary

Gitea's Debian package registry parser contains an unbounded decompression vulnerability in [ParseControlFile](https://github.com/go-gitea/gitea/blob/689ace1ce28fd74244b8aa335d9928cdbf6b22f9/modules/packages/debian/metadata.go#L140). When processing an uploaded `.deb` file, the parser decompresses `control.tar.gz` and copies the entire uncompressed stream into a `strings.Builder` via a `TeeReader`, with no limit on how much data is read. Because `DEFLATE` compression can achieve ratios exceeding 100:1 on repetitive input, an attacker can craft an 83 MB `.deb` payload that expands to over 16 GB during parsing, exhausting server memory before any content validation runs. A second issue compounds this: continuation lines in the Description field are concatenated with `+=` at [modules/packages/debian/metadata.go:161](https://github.com/go-gitea/gitea/blob/689ace1ce28fd74244b8aa335d9928cdbf6b22f9/modules/packages/debian/metadata.go#L161) inside a loop, producing `O(N²)` allocation and copy work that stalls the CPU even at moderate line counts. Any authenticated user with write access to the package registry can trigger a complete denial of service with a single upload request to the handler at [routers/api/packages/debian/debian.go:146](https://github.com/go-gitea/gitea/blob/689ace1ce28fd74244b8aa335d9928cdbf6b22f9/routers/api/packages/debian/debian.go#L146). ### Root Cause There are two distinct root causes that can be exploited independently or together. **1. Unbounded decompression (decompression bomb)** ParsePackage wraps the control.tar member in a decompressor but never constrains how many bytes that decompressor is allowed to produce: https://github.com/go-gitea/gitea/blob/9155a81b9daf1d46b2380aa91271e623ac947c1e/modules/packages/debian/metadata.go#L88-L110 The resulting inner reader is passed directly to the tar reader, and from there to `ParseControlFile`. Inside `ParseControlFile`, every byte that the `bufio.Scanner` reads from the decompressed stream is simultaneously written into an unbounded `strings.Builder` via `io.TeeReader`: https://github.com/go-gitea/gitea/blob/9155a81b9daf1d46b2380aa91271e623ac947c1e/modules/packages/debian/metadata.go#L147-L150 There is no call to io.LimitReader at any point in this chain. Other package format parsers in the same codebase — pub, conan, and cargo — all wrap their readers with `io.LimitReader` before consuming them. The Debian parser does not, making it the only one in the registry vulnerable to this class of attack. **2. O(N²) string concatenation** For each continuation line belonging to the Description field, the parser appends to a plain string with +=: https://github.com/go-gitea/gitea/blob/9155a81b9daf1d46b2380aa91271e623ac947c1e/modules/packages/debian/metadata.go#L158-L164 Because Go strings are immutable, every `+=` allocates a new backing array and copies the entire accumulated description into it. A description with N continuation lines triggers O(N²) total bytes of allocation and copying. At 500 000 lines this produces roughly 250 GB of cumulative copy work, saturating a CPU core and driving the GC into a tight collection loop regardless of available RAM. ### Reproducing I have reproduced the issue in a Docker container with the following PoC. It may need tweaks based on the memory you are reproducing it with. This has been reproduced on commit `9155a81b9daf1d46b2380aa91271e623ac947c1e`. All the files go in the gitea file directory. `cmd/poc/main.go` ```go package main import ( "archive/tar" "bytes" "compress/gzip" "fmt" "io" "os" "runtime" "strings" "time" "github.com/blakesmith/ar" debian_module "gitea.dev/modules/packages/debian" ) // targetUncompressed is the desired size of the uncompressed control file. // Set comfortably above the 12 GB container limit so the OOM kill is reliable. const targetUncompressed = 15 * 1024 * 1024 * 1024 // 15 GB // padLine is the filler field written after the required package fields. // Using an unkno

Affected packages

EcosystemPackageAffected versionsFixed versions
Gocode.gitea.io/gitea1.27.0

Remediation: Upgrade to 1.27.0 or later.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.

CVE® is a registered trademark of The MITRE Corporation. CVE content reproduced under the CVE Terms of Use; copyright designation © MITRE.