Skip to main content

Gitea CVE-2026-23603

| EUVDEUVD-2026-58134 LOW
Server-Side Request Forgery (SSRF) (CWE-918)
2026-07-21 https://github.com/go-gitea/gitea GHSA-x77v-q46j-393g
3.1
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
    Attacker sets OIDC picture claim to internal URL
  2. Delivery
    Authenticates via configured OAuth2/OIDC source
  3. Exploit
    Gitea invokes oauth2UpdateAvatarIfNeed() on login
  4. Execution
    Unrestricted http.Get() issues outbound request
  5. Persist
    Server reaches loopback, RFC1918, or cloud metadata endpoint
  6. Impact
    Blind SSRF probes internal network or partially retrieves image-format response via avatar storage

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V4 - API and Web Service URL allowlisting, SSRF prevention
MITRE ATT&CK

2 techniques across 2 tactics: Initial Access, Credential Access

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

Exploitation Conditions

Exploitation requires three specific conditions to hold simultaneously: (1) [oauth2_client] UPDATE_AVATAR = true must be set in app.ini - this is not the default configuration and must be explicitly enabled; (2) at least one OAuth2 or OIDC authentication source must be configured and active in Gitea; and (3) the attacker must be able to control the picture claim value returned by the configured identity provider for their own account - this is possible with a self-hosted IdP, a provider permitting custom claims, or an attacker-operated fake OIDC endpoint. CVSS PR:L confirms a low-privileged OAuth2 account relationship is required; unauthenticated exploitation is not possible. The SSRF is blind by default: non-image HTTP responses are silently discarded during avatar processing and not returned to the attacker. Response retrieval is only partially possible when an internal endpoint returns a valid image format within the configured avatar size limit (setting.Avatar.MaxFileSize). Exploitation is further limited to HTTP GET - no POST or body-bearing requests are issued.

Impact

The CVSS 3.1 base score of 3.1 (AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N) correctly captures the limited baseline impact - blind SSRF with no direct data return path and high attack complexity due to the IdP picture claim control requirement. However, this score significantly underrepresents risk in cloud-hosted Gitea deployments where the server can reach 169.254.169.254 or IMDSv1 endpoints; in those environments, SSRF against metadata services can yield cloud credentials and escalate impact to Critical. EPSS data was not provided in the input and cannot be assessed. The vulnerability is not listed in CISA KEV, so confirmed active exploitation is not established. A functional PoC is documented in the advisory, lowering the exploitation barrier. The AC:H rating reflects that the attacker must control their own OIDC picture claim under an already-configured IdP - achievable with a self-hosted or permissive IdP but not universally trivial. On-premises deployments with no internal services accessible from the Gitea host are genuinely low risk at the stated CVSS score; cloud deployments should treat this as higher priority.

Exploit ScenarioDerived

An attacker with a low-privileged account authenticates to Gitea via a configured OAuth2/OIDC source backed by an IdP they control or can manipulate, setting their picture claim to http://169.254.169.254/latest/meta-data/iam/security-credentials/. Upon login, Gitea's server calls http.Get() on that URL from its own network position, issuing an unauthenticated HTTP request to the cloud instance metadata service; if the response is a valid image within the avatar size limit, it may be stored as the attacker's avatar, partially leaking the response. A functional PoC using a fake OIDC provider is included in the vendor advisory.

Monitor Track and reassess. Why: LOW severity (CVSS 0.1-3.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

Blind server-side request forgery in Gitea's OAuth2 avatar synchronization path allows a low-privileged authenticated user to force the server to issue arbitrary outbound HTTP GET requests to attacker-controlled URLs. Gitea versions prior to 1.27.0, when configured with [oauth2_client] UPDATE_AVATAR = true, call Go's unrestricted http.Get() on the OIDC picture claim without applying the hostmatcher.NewDialContext restrictions used elsewhere in the codebase - enabling requests to loopback, RFC1918, and cloud metadata addresses such as 169.254.169.254. No active exploitation is confirmed in CISA KEV, but a functional proof-of-concept is included in the vendor advisory, and the fix is available in Gitea v1.27.0.

RemediationAI

Vendor-released patch: Gitea v1.27.0, available at https://github.com/go-gitea/gitea/releases/tag/v1.27.0. The fix is implemented in PRs #38406 (https://github.com/go-gitea/gitea/pull/38406) and #38426 (https://github.com/go-gitea/gitea/pull/38426), which apply hostmatcher.NewDialContext-based host filtering to the OAuth2 avatar fetch path via the unified ALLOWED_HOST_LIST configuration. If immediate upgrade is not feasible, the most direct compensating control is setting UPDATE_AVATAR = false under [oauth2_client] in app.ini, which disables the vulnerable code path entirely with no side effect other than preventing automatic avatar synchronization from OAuth2/OIDC providers. As a secondary layer, network egress filtering at the host or container level to block the Gitea process from reaching 169.254.169.254, RFC1918 ranges, and loopback addresses reduces SSRF impact but does not eliminate the vulnerability and may interfere with legitimate internal service connectivity. Advisory: https://github.com/go-gitea/gitea/security/advisories/GHSA-x77v-q46j-393g.

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 vulnerable sink is oauth2UpdateAvatarIfNeed() in routers/web/auth/oauth.go, which invokes Go's default http.Get(url) on the AvatarURL field sourced from the OAuth2/OIDC provider's goth.User struct - commonly populated from the OIDC picture claim in the userinfo endpoint or ID token. CWE-918 (Server-Side Request Forgery) applies: the server makes outbound requests on behalf of an attacker without validating the destination host. Critically, Gitea's own repository migration code uses hostmatcher.NewDialContext to enforce TCP-level allow-listing, but this protection was absent from the OAuth2 avatar path until v1.27.0. The fix (PRs #38406 and #38426) moves the ALLOWED_HOST_LIST configuration to a shared scope covering both webhooks and OAuth2 client fetches. Affected package: pkg:go/code.gitea.io_gitea versions < 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 3.1 LOW
AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
vuln.today AI 3.1 LOW

Network vector for OAuth2 login flow; AC:H because attacker must control their own IdP picture claim; PR:L for required low-privileged account; C:L for blind SSRF with limited partial response retrieval; no integrity or availability impact.

3.1 AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N
4.0 AV:N/AC:H/AT:P/PR:L/UI:N/VC:L/VI:N/VA:N/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
High
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
None

DescriptionCVE.org

Summary

When [oauth2_client] UPDATE_AVATAR = true is enabled, Gitea fetches the avatar URL received from an OAuth2/OIDC provider using Go's default HTTP client. The URL comes from the user's OAuth/OIDC avatar value, commonly the OIDC picture claim.

The affected code path calls http.Get(url) without applying outbound host or IP restrictions. A low-privileged user who can influence their own picture claim under an already-configured OAuth2/OIDC source can cause the Gitea server to make arbitrary outbound HTTP GET requests. This includes requests to loopback addresses, RFC 1918 private network addresses, and IPv4 link-local addresses such as 169.254.169.254.

This is a blind SSRF by default. Impact can increase in deployments where the Gitea host can reach cloud metadata services, localhost-only services, or internal services that return valid image data.

Details

The vulnerable sink is in routers/web/auth/oauth.go:

go
func oauth2UpdateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
    if setting.OAuth2Client.UpdateAvatar && len(url) > 0 {
        resp, err := http.Get(url)
        if err == nil {
            defer func() { _ = resp.Body.Close() }()
        }
        if err == nil && resp.StatusCode == http.StatusOK {
            data, err := io.ReadAll(io.LimitReader(resp.Body, setting.Avatar.MaxFileSize+1))
            if err == nil && int64(len(data)) <= setting.Avatar.MaxFileSize {
                _ = user_service.UploadAvatar(ctx, u, data)
            }
        }
    }
}

The caller is in routers/web/auth/oauth_signin_sync.go:

go
func oauth2SignInSync(ctx *context.Context, authSourceID int64, u *user_model.User, gothUser goth.User) {
    oauth2UpdateAvatarIfNeed(ctx, gothUser.AvatarURL, u)
    ...
}

gothUser.AvatarURL is derived from the OAuth2/OIDC provider's avatar value. For OIDC providers, this is commonly populated from the picture claim returned by the provider's userinfo endpoint or ID token.

The issue is that this value can be attacker-influenced in some common IdP configurations, while Gitea fetches it server-side using http.Get with no host/IP validation and no restricted transport.

Comparable outbound fetch paths in Gitea use hostmatcher.NewDialContext to enforce restrictions at TCP dial time. For example, repository migration uses an HTTP transport with host matching. The OAuth2 avatar synchronization path does not apply those restrictions.

PoC

Requirements
  • Local Gitea build or binary
  • Python 3
  • Python packages: requests, pyjwt, cryptography
  • Gitea configured with OAuth2 avatar synchronization enabled

Install Python dependencies:

bash
python3 -m pip install requests pyjwt cryptography

Configure app.ini:

ini
[oauth2_client]
UPDATE_AVATAR = true
ENABLE_AUTO_REGISTRATION = true
USERNAME = userid

Run the fake OIDC provider:

bash
python3 fake_oidc.py http://127.0.0.1:8888/ 9999

Run a listener for the SSRF target:

bash
nc -lvnp 8888

Register an OAuth2 authentication source in Gitea:

  • Provider: OpenID Connect
  • Client ID: gitea-client
  • Client Secret: gitea-secret
  • OpenID Connect Auto Discovery URL: http://127.0.0.1:9999/.well-known/openid-configuration

Then initiate login through the configured OAuth2 source.

Observed request to the SSRF listener:

http
GET / HTTP/1.1
Host: 127.0.0.1:8888
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

Observe that Gitea fetched the OIDC picture claim URL from the server side using the default Go HTTP client.

Impact

When [oauth2_client] UPDATE_AVATAR = true is enabled, a low-privileged OAuth2/OIDC user who can influence their own picture claim can force the Gitea server to make outbound HTTP GET requests to attacker-selected URLs. This allows blind SSRF from the Gitea server’s network position, including requests to loopback addresses, RFC1918 private addresses, link-local addresses such as 169.254.169.254, and other internal services that may not be reachable from the public internet. In practical terms, this can enable internal service probing and interaction with localhost-only or private-network services depending on the deployment’s network access controls.

The vulnerability is blind in the common case because non-image responses such as HTML, JSON, or plaintext are rejected during avatar processing and are not directly returned to the attacker. However, impact can increase in cloud or internal-network deployments where metadata services, internal admin panels, monitoring endpoints, or image-generating internal services are reachable from the Gitea host. If an internal endpoint returns a valid supported image format within the configured avatar size limit, the response may be stored as the attacker’s avatar, creating a limited response retrieval primitive.

Threat Intelligence Overview

EPSS Score
0.2%
Top 95% exploitable
Prevalence
Medium
widely used self-hosted Git platform among developers and enterprises
Threat Intel
1
1 source
Data Quality
5 sources
Confidence: Medium

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 LOW
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
LOW severity (CVSS 0.1-3.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
Defer
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
No
Human Impact· derived
Low

Priority Score

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

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

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