CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-wwqq-x6w4-frm2: Gitea: Denial of Service via Unbounded io.ReadAll in NPM Package Tag Endpoint

mediumCVSS 6.5CVE-2026-42931
Summary An unbounded io.ReadAll(ctx.Req.Body) call in the NPM package tag API endpoint allows any authenticated user to crash the Gitea server by sending a single large HTTP request. The request body is read entirely into memory with no size limit, causing an Out-of-Memory (OOM) kill. With concurrent requests, the attack produces a persistent denial of service that survives automatic restarts. Details The AddPackageTag function reads the entire HTTP request body into memory using io.ReadAll() with no size validation: // routers/api/packages/npm/npm.go:332-341 func AddPackageTag(ctx *context.Context) { packageName := packageNameFromParams(ctx) body, err := io.ReadAll(ctx.Req.Body) // NO SIZE LIMIT if err != nil { apiError(ctx, http.StatusInternalServerError, err) return } version := strings.Trim(string(body), "\"") // ... } This route is registered at routers/api/packages/api.go:433: r.Group("/-/package/{id}/dist-tags", func() { // ... r.Group("/{tag}", func() { r.Put("", npm.AddPackageTag) // reqPackageAccess(perm.AccessModeWrite) r.Delete("", npm.DeletePackageTag) }) }) Why this causes OOM and not just a slow request: In Go, io.ReadAll() reads into a []byte that grows dynamically. When the incoming data exceeds available memory, the Go runtime attempts to allocate a larger backing array. This allocation fails, triggering an unrecoverable runtime.throw("out of memory") that kills the entire process, not just the goroutine handling the request. No server-side size limits apply to this endpoint: Gitea has per-type size limits (e.g., LIMIT_SIZE_NPM) defined in modules/setting/packages.go, but these are only enforced during UploadPackage, not in AddPackageTag. The mustBytes() function defaults all limits to -1 (unlimited) when not explicitly configured: // modules/setting/packages.go:96-101 func mustBytes(section ConfigSection, key string) int64 { const noLimit = "-1" value := section.Key(key).MustString(noLimit) // defaults to "-1" if value == noLimit { retur

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
medium — CVSS 6.5
Published
2026-07-21
Last updated
2026-07-21
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-wwqq-x6w4-frm2

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-42931coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories