Skip to main content

Gitea CVE-2026-56443

| EUVDEUVD-2026-58142 CRITICAL
Incorrect Authorization (CWE-863)
2026-07-21 https://github.com/go-gitea/gitea GHSA-7p4h-3gxq-x3h3
Critical
Disputed · 9.6 Vendor: https://github.com/go-gitea/gitea
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Register or reuse Gitea account
  2. Delivery
    Mint public-only PAT with repo/package scopes
  3. Exploit
    Call Limited-owner repo/package/git endpoint
  4. Execution
    IsPrivate() check falls through for VisibleTypeLimited
  5. Impact
    Read internal content and clone repositories

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 target owner (a user or an organization) must be configured with Visibility = Limited (instance-internal); Public owners expose nothing extra and Private owners are correctly blocked. The attacker must hold a valid account on the same Gitea instance and a Personal Access Token carrying the public-only modifier with read:repository and/or read:package scopes (PR:L - authenticated). Exploitation is limited to READ operations: writes are rejected (PoC PROBE N returns 403), so integrity is not affected. It is exercisable across API v1 repository endpoints, all native package registries, web /raw, /media, /attachments, and LFS/git smart-HTTP routes. It does NOT work anonymously (baseline returns 401/404) and does NOT affect the User, Org, or ActivityPub scope categories, which were already fixed by CVE-2026-25714 / PR #37118.

Impact

Signals conflict and must be weighed carefully. The published CVSS is 9.6 (Critical) with vector AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H, but that impact profile (Integrity/Availability High, Confidentiality None) contradicts the reporter's own PoC: PROBE N shows writes are rejected ('user should have a permission to write to the target branch'), explicitly confirming Integrity:N, and the actual demonstrated harm is unauthorized READING of internal content - a confidentiality issue. The scored vector therefore appears mis-encoded; the realistic profile is a read-only information-disclosure bypass, closer to CVSS Medium. Exploitation requires a valid instance account (PR:L) to mint a PAT, and only bites when the target owner uses Limited visibility, so it is not a fully unauthenticated internet-wide flaw. EPSS (0.17%, 6th percentile) and absence from CISA KEV both indicate no observed mass exploitation. A working PoC exists, lowering the barrier, but real-world priority is moderate: important for multi-tenant/internal Gitea instances that rely on Limited visibility as a confidentiality boundary, lower for instances that only use Public and Private.

Exploit ScenarioDerived

An attacker registers (or already holds) an ordinary account on a shared Gitea instance and mints a Personal Access Token with the public-only modifier plus read:repository/read:package scopes, believing the token is confined to public data. Using that token against a Limited-visibility user's or organization's repositories and package registries, the attacker downloads internal source, package artifacts, and performs full git clones via git-upload-pack - content anonymous users are denied (401/404). A vendor-verified Docker PoC (run-poc.sh) demonstrates the full chain, including the Limited-org variant.

Act Now Prioritize within 24-48h. Why: CRITICAL severity.
Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv2 – Aug 14, 2026

Authorization bypass in Gitea before 1.27.0 lets a public-only Personal Access Token read internal content owned by Limited-visibility users and organizations, exceeding the reach the scope is meant to grant. The Repository and Package scope categories only test repo.IsPrivate / Owner.Visibility.IsPrivate(), which return false for VisibleTypeLimited, so an authenticated attacker with a public-only PAT can fetch READMEs, repo content, packages from all 24 registries, and even perform full git-upload-pack clones of instance-internal projects. A vendor-verified end-to-end Docker PoC exists (publicly available exploit code exists); it is not in CISA KEV and EPSS is low at 0.17% (6th percentile). This is the residual gap left after CVE-2026-25714 / PR #37118 fixed the sibling User/Org/ActivityPub cases.

Earlier versions of this analysis (1)
v1 Jul 21, 2026 - 21:08 CVSS 4.3

Public-only PAT scope enforcement in Gitea is bypassed for Repository and Package categories when the resource owner has Visibility = Limited (instance-internal), allowing a low-privileged attacker with a public-only token to read internal content that exceeds anonymous reach. Affected are all API v1 Repository endpoints, all 24 native package registries, web download routes (/raw, /media, /attachments), and LFS routes in Gitea versions prior to 1.27.0. This is a residual authorization gap after CVE-2026-25714 / PR #37118; a verified proof-of-concept script exists, confirmed on gitea/gitea:1.26.2 as of 2026-06-05, and no public exploit has been confirmed as actively exploited in CISA KEV at time of analysis.

RemediationAI

Vendor-released patch: 1.27.0 - upgrade Gitea to 1.27.0 or later (release https://github.com/go-gitea/gitea/releases/tag/v1.27.0, notes https://blog.gitea.com/gitea-1.27.0-is-released/), which realigns the Repository and Package scope checks to use !Visibility.IsPublic() consistent with the User/Org/ActivityPub cases. If immediate upgrade is not possible, the most effective compensating control is to avoid relying on Limited visibility as a security boundary: convert genuinely sensitive owners/repositories/packages to Private (which IsPrivate() correctly blocks), accepting that they will no longer be visible to legitimate signed-in users. As a broader lock-down you can disable creation of public-only tokens or audit and revoke existing PATs, and restrict who can register accounts on the instance (since exploitation needs an authenticated account), at the cost of reduced automation/self-service. There is no reliable per-endpoint firewall workaround because the leak spans API v1 repository endpoints, all 24 package registries, web /raw, /media, /attachments, and LFS/git-upload-pack routes.

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

Gitea supports three owner visibility levels - Public, Limited (visible only to signed-in instance users), and Private. Personal Access Tokens can carry a 'public-only' modifier that is supposed to restrict a token to what an anonymous user could see. The central gatekeeper checkTokenPublicOnly (routers/api/v1/api.go) and its helpers TokenCanAccessRepo (services/context/api.go), CheckTokenScopes (services/context/permission.go:32), and the reqPackageAccess middleware (routers/api/packages/api.go:76) enforce this. The root cause is CWE-863 (Incorrect Authorization): the Org/User/ActivityPub branches correctly reject non-public owners with !Visibility.IsPublic(), but the Repository and Package branches use IsPrivate(), where VisibleType.IsPrivate() returns true only for VisibleTypePrivate and falls through for VisibleTypeLimited. Because 'not private' is not the same as 'public', a public-only token gains strictly more reach than anonymous access on Limited owners. Affected package identifier is pkg:go/code.gitea.io/gitea.

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

Sources disagree (Medium–Critical)
Vendor (https://github.com/go-gitea/gitea) PRIMARY 9.6 CRITICAL
AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H
vuln.today AI 6.5 MEDIUM

Authenticated attacker mints a public-only PAT (PR:L) over the network with low complexity; impact is unauthorized read of Limited-visibility content (C:H), while writes are blocked (I:N) and there is no availability impact (A:N).

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:N/SI:N/SA:N
SUSE MEDIUM

vuln.today treats the vendor’s rating as authoritative. A higher third-party CVSS (e.g. CISA-ADP) is shown for transparency but does not drive the headline severity.

CVSS VectorVendor: https://github.com/go-gitea/gitea

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
None
Integrity
High
Availability
High

Lifecycle Timeline

3
Analysis Updated
Aug 14, 2026 - 20:34 vuln.today
v2 - CVSS changed
Severity Changed
Aug 14, 2026 - 20:22 NVD
MEDIUM CRITICAL
CVSS changed
Aug 14, 2026 - 20:22 NVD
4.3 (MEDIUM) 9.6 (CRITICAL)

DescriptionCVE.org

Summary

After PR #37118 / CVE-2026-25714 (fix: Unify public-only token filtering in API queries and repo access checks, merged 2026-05-18, backport #37773 to 1.26.2 - the May 2026 unification pass for public-only token filtering, reporter Medoedus per the 1.26.2 release notes), the public-only PAT scope is still bypassable on Repository and Package scope categories when the owner's Visibility = Limited (instance-internal).

The sibling Org / User / ActivityPub cases in the same checkTokenPublicOnly switch correctly reject Limited owners via !Visibility.IsPublic(). The Repository / Package cases use repo.IsPrivate or Owner.Visibility.IsPrivate(), both of which return false for VisibleTypeLimited - so a public-only PAT strictly exceeds anonymous reach on a Limited owner.

Tested on gitea/gitea:1.26.2. The decisive marker is that PR #37118's unification IS applied in the version under test (User-category PROBE returns 403 "token scope is limited to public users"). Despite that, the Repository-category PROBE on the same Limited owner with the same PAT returns 200 and serves content.

Affected entry points (4 spots)

File:LineFunctionAffected surface
routers/api/v1/api.go:292checkTokenPublicOnly Package caseAPI v1 packages
routers/api/packages/api.go:76reqPackageAccess middlewareAll 24 native package registries (/api/packages/<type>/...)
services/context/api.goTokenCanAccessRepo helperAll API v1 Repository-category endpoints - content, issues, PRs, releases, labels, milestones, etc.
services/context/permission.go:32CheckTokenScopes (called via CheckRepoScopedToken)Web download endpoints /raw, /media, /attachments. LFS routes (services/lfs/server.go:470/472, services/lfs/locks.go:62/151/216/284) also chain through this helper.

All four sinks check repo.IsPrivate or Owner.Visibility.IsPrivate() only. VisibleTypeLimited falls through.

go
// modules/structs/visible_type.go
func (vt VisibleType) IsPrivate() bool { return vt == VisibleTypePrivate }   // line 39-40
func (vt VisibleType) IsLimited() bool { return vt == VisibleTypeLimited }   // line 33-34

Same-file evidence (routers/api/v1/api.go:246-299 after PR #37118)

go
case auth_model.AccessTokenScopeCategoryOrganization:
    orgPrivate := ... && !ctx.Org.Organization.Visibility.IsPublic()        // !IsPublic ✓
case auth_model.AccessTokenScopeCategoryUser:
    if ... && !ctx.ContextUser.Visibility.IsPublic() { ... }                // !IsPublic ✓
case auth_model.AccessTokenScopeCategoryActivityPub:
    if ... && !ctx.ContextUser.Visibility.IsPublic() { ... }                // !IsPublic ✓

case auth_model.AccessTokenScopeCategoryPackage:
    if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() {     // IsPrivate ONLY ✗
        ctx.APIError(http.StatusForbidden, "token scope is limited to public packages")
        return
    }

TokenCanAccessRepo (services/context/api.go) reduces to !repo.IsPrivate:

go
// A public-only token cannot reach a private repo; any other token is unrestricted by this check.
func (ctx *APIContext) TokenCanAccessRepo(repo *repo_model.Repository) bool {
    return repo == nil || !ctx.PublicOnly || !repo.IsPrivate
}

CheckTokenScopes (services/context/permission.go:32):

go
if publicOnly && repo != nil && repo.IsPrivate {
    ctx.HTTPError(http.StatusForbidden)
    return
}

PoC (Docker e2e VERIFIED on gitea/gitea:1.26.2, 2026-06-05)

Full script in the report (run-poc.sh). Setup:

  1. Create user limuser. PATCH /api/v1/admin/users/limuser with body

{"visibility":"limited", ...} - response confirms "visibility":"limited".

  1. Upload a generic package as limuser:

PUT /api/packages/limuser/generic/secretpkg/1.0.0/secret.txt with body secret-content-internal-only → 201.

  1. Create user attacker.
  2. Mint PAT for attacker with scopes=["read:package","read:user","read:repository","public-only"].

Result on gitea/gitea:1.26.2 - nine PROBEs:

PROBE A  (download package via attacker PAT)
    HTTP=200  Body: secret-content-internal-only

PROBE C  (read README of limuser's PUBLIC repo)
    HTTP=200  Body: {"name":"README.md", ...}

PROBE F  (sanity - User category, same PAT, same owner)
    HTTP=403  Body: {"message":"token scope is limited to public users"}

PROBE G  (Repository category, same PAT, same owner)
    HTTP=200  Body: {"name":"README.md", ...}                    ← bypass

PROBE H  (list limuser's repos, User category)
    HTTP=403  Body: {"message":"token scope is limited to public users"}

PROBE M  (git HTTPS smart protocol - info/refs)
    HTTP=200  Body: 001e
# service=git-upload-pack ... HEAD ...   ← full clone enabled

PROBE N  (write attempt: POST contents/hacked.txt)
    HTTP=403  Body: {"message":"user should have a permission to write to the target branch"}
                                                                    Integrity:N confirmed

PROBE O  (Limited ORG - same bypass class)
    Org category    : HTTP=403  {"message":"token scope is limited to public orgs"}
    Repo category   : HTTP=200  README content                  ← bypass

Anonymous baseline (no auth) on every above endpoint: HTTP=401/404

Gitea's own server error string in PROBE F / H / O - *"token scope is limited to public users"* / *"public orgs"* - is the explicit declaration of intent. Repository / Package category violates that intent on the same Limited owner.

Why this is not a duplicate of CVE-2026-25714

CVE-2026-25714 / PR #37118 (the May 2026 unification pass for public-only token filtering, merged 2026-05-18, backported to 1.26.2 via PR #37773) realigned checkTokenPublicOnly's Org / User / ActivityPub cases on !Visibility.IsPublic() and introduced the TokenCanAccessRepo helper for the Repository / Issue / Notification cases.

PROBE F on 1.26.2 returns 403 "token scope is limited to public users" for the User category - i.e. PR #37118's unification IS in effect on the version under test. The Repository / Package leak occurs *after* that fix; the Limited gap is the next residual issue on the same hygiene effort (the Package case was not touched, and TokenCanAccessRepo reduces to !repo.IsPrivate without consulting owner visibility), not the same bug.

Suggested fix (4 spots, 1-line shape each)

go
// routers/api/v1/api.go:292  (checkTokenPublicOnly Package case)
- if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() {
+ if ctx.Package != nil && !ctx.Package.Owner.Visibility.IsPublic() {

// routers/api/packages/api.go:76  (reqPackageAccess middleware)
- if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() {
+ if ctx.Package != nil && !ctx.Package.Owner.Visibility.IsPublic() {

// services/context/api.go  (TokenCanAccessRepo helper)
- return repo == nil || !ctx.PublicOnly || !repo.IsPrivate
+ return repo == nil || !ctx.PublicOnly ||
+     (!repo.IsPrivate && repo.Owner != nil && repo.Owner.Visibility.IsPublic())

// services/context/permission.go:32  (CheckTokenScopes)
- if publicOnly && repo != nil && repo.IsPrivate {
+ if publicOnly && repo != nil &&
+     (repo.IsPrivate || (repo.Owner != nil && !repo.Owner.Visibility.IsPublic())) {

This aligns the Repository / Package categories with the User / Org / ActivityPub siblings already shipped in PR #37118.

Reporter

JebeenLee

Executive ViewAI

Why It Matters

Gitea versions before 1.27.0 have a critical authorization bypass flaw in Personal Access Token validation that allows public-only tokens to access confidential internal repositories, packages, and code restricted to Limited-visibility users and organizations. An authenticated attacker with a public-only PAT can read internal READMEs, repository content, and clone entire internal projects without proper authorization. This directly exposes organizational intellectual property to theft or unauthorized disclosure.

Business Impact: Severe
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.2%
Top 94% exploitable
Prevalence
Medium
popular self-hosted Git server, common but not enterprise-ubiquitous
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 CRITICAL
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
CRITICAL severity
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
Very High

Priority Score

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