Skip to main content

Gitea CVE-2026-58437

HIGH
Improper Access Control (CWE-284)
2026-07-21 https://github.com/go-gitea/gitea GHSA-8p9h-49rc-qgxj
7.1
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
7.1 HIGH
AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N
vuln.today AI
7.1 HIGH

Requires repo owner/admin-collaborator role (PR:L) over the Git network protocol with low complexity; flipping a private repo public fully exposes its contents (C:H), while integrity impact is limited to toggling settings flags (I:L).

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

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
High
Availability
None

Lifecycle Timeline

3
Source Code Evidence Fetched
Jul 21, 2026 - 21:36 vuln.today
Analysis Generated
Jul 21, 2026 - 21:36 vuln.today
CVE Published
Jul 21, 2026 - 21:02 github-advisory
HIGH 7.1

DescriptionGitHub Advisory

Repository Visibility Manipulation via Git Push Options

FieldValue
Affected Filerouters/private/hook_post_receive.go
Affected FunctionHookPostReceive()
Affected Lines173-225
PrerequisiteAttacker must have owner-level or admin collaborator access to the target repository

---

Description

Gitea's post-receive git hook handler processes git push options - key-value pairs transmitted by a client during git push using the -o flag. Two undocumented push options, repo.private and repo.template, allow any user with repository owner or admin-collaborator access to toggle the visibility (private/public) and template status of a repository as a side effect of a normal git push.

This capability was originally intended solely for the "push-to-create" feature (automatically creating a repo on first push). However, the options are processed without restriction on already-existing repositories, and - critically - the visibility change bypasses every control that a proper settings change would trigger:

  • No entry written to the repository's audit/activity log
  • No webhook event fired (repository event with visibility_changed action)
  • No org-level notification to owners
  • No team permission re-calculation
  • No email alert to watchers
  • The database update uses UpdateRepositoryColsNoAutoTime, which also suppresses the updated_at timestamp change

---

Vulnerable Code

routers/private/hook_post_receive.go:173-225

go
isPrivate  := opts.GitPushOptions.Bool(private.GitPushOptionRepoPrivate)  // "repo.private"
isTemplate := opts.GitPushOptions.Bool(private.GitPushOptionRepoTemplate) // "repo.template"

if isPrivate.Has() || isTemplate.Has() {
    // ... loads repo and verifies pusher is owner or admin ...
    if !perm.IsOwner() && !perm.IsAdmin() {
        ctx.JSON(http.StatusNotFound, ...)
        return
    }

    // FIXME: these options are not quite right, for example: changing visibility
    //        should do more works than just setting the is_private flag
    // These options should only be used for "push-to-create"
    if isPrivate.Has() && repo.IsPrivate != isPrivate.Value() {
        // TODO: it needs to do more work
        repo.IsPrivate = isPrivate.Value()
        repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "is_private")
        //         ^^^ bypasses updated_at timestamp, audit trail suppressed
    }
    if isTemplate.Has() && repo.IsTemplate != isTemplate.Value() {
        repo.IsTemplate = isTemplate.Value()
        repo_model.UpdateRepositoryColsNoAutoTime(ctx, repo, "is_template")
    }
}

The push option constants are defined in modules/private/pushoptions.go:18-19:

go
GitPushOptionRepoPrivate  = "repo.private"
GitPushOptionRepoTemplate = "repo.template"

---

Attack Scenario

Scenario A - Insider threat / rogue admin collaborator

An organization grants a contractor repo admin access to contribute to a private repository containing proprietary source code. The contractor, before their access is revoked, makes a private repo public for several minutes - long enough to clone, archive, or index the content - then makes it private again. The action leaves no audit trail distinguishable from a normal git push.

Scenario B - Supply-chain template poisoning

A repository marked as a template is used by CI/CD pipelines to generate new project repositories. An admin collaborator uses repo.template=false to silently remove the template designation, then makes changes to the repo's content, re-marks it as a template with repo.template=true, and waits for downstream consumers to regenerate projects from the now-backdoored template. The updated_at timestamp is unchanged due to UpdateRepositoryColsNoAutoTime, making diff-detection harder.

---

Step-by-Step Reproduction

Prerequisites:

  • A Gitea user account with either owner or admin-collaborator access to a private repository
  • git client with push access to the repository

---

Step 1 - Confirm the target repository is private

---

Step 2 - Clone the repository

bash
git clone http://USER:PASSWORD@<gitea-host>/OWNER/REPO.git /tmp/target-repo
cd /tmp/target-repo

---

Step 3 - Make any commit *(the push option rides on a real push)*

bash
echo "$(date)" >> .gitkeep
git add .gitkeep
git commit -m "routine update"

---

Step 4 - Execute the exploit push

bash
# Make the repository public
git push http://USER:PASSWORD@<gitea-host>/OWNER/REPO.git main \
  -o repo.private=false
# The push completes with a normal success message:
#   remote: Processed 1 references in total
#   To http://<gitea-host>/OWNER/REPO.git
#      abc1234..def5678  main -> main

---

Step 5 - Verify the repository is now public

---

Step 6 - Restore and cover tracks

Re-make it private in the same session, leaving no visible audit trail

The repository activity feed shows only two normal push events. The visibility change is invisible.

Verification: confirm no activity log entry

---

Impact Details
ImpactDescription
Data exfiltrationPrivate source code, CI/CD secrets in plain-text files, environment configs become publicly cloneable for the window the repo is public
No audit trailUpdateRepositoryColsNoAutoTime suppresses the updated_at change; no activity log entry; no webhook; no notification
Supply chainCombined with repo.template=true/false, an attacker can silently rotate repository template status, affecting all downstream repositories that generate from this template
ScopeAffects all repos where the attacker has admin-collaborator access - not only repos they own

---

Recommended Fix

Option 1 (preferred) - Remove the options from post-receive hook entirely. The repo.private and repo.template push options were designed for the push-to-create flow and have no legitimate use on existing repositories. They should be gated with:

go
// routers/private/hook_post_receive.go
if isPrivate.Has() || isTemplate.Has() {
    if !wasEmpty {
        // repo already existed - refuse these options on established repos
        log.Warn("Repo push options repo.private/repo.template ignored for existing repo %s", repoName)
        // do not process
    } else {
        // original push-to-create path only
        ...
    }
}

Option 2 - Route through the full visibility-change service so that audit events, webhooks, and team re-syncs are triggered:

go
// Instead of the raw UpdateRepositoryColsNoAutoTime call:
if err := repo_service.UpdateRepositoryVisibility(ctx, repo, isPrivate.Value()); err != nil {
    ...
}

Where UpdateRepositoryVisibility fires the repository webhook event and writes an activity log entry.

AnalysisAI

Repository visibility and template status in Gitea (self-hosted Git service) before 1.27.0 can be silently toggled by any repository owner or admin-collaborator through undocumented git push options (repo.private, repo.template) processed by the post-receive hook, bypassing all audit logging, webhooks, and notifications. An insider can flip a private repository to public long enough to clone proprietary code, then revert it, leaving only two ordinary push events in the activity feed. …

Unlock full vulnerability intelligence

  • Risk assessment & exploitation conditions
  • Attack chain visualization
  • Remediation with exact patch versions
  • Threat intelligence from 22 sources
  • Personal watchlist & email alerts

Free forever · No credit card required

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata

Recon
Obtain owner/admin-collaborator access to private repo
Delivery
Clone and make a routine commit
Exploit
Push with -o repo.private=false
Install
Repository silently becomes public
C2
Clone/archive exposed source and secrets
Execute
Push with -o repo.private=true to restore
Impact
No audit trail, webhook, or timestamp change

Vulnerability AssessmentAI

Exploitation The attacker must already hold owner-level or admin-collaborator access on the target Gitea repository and have Git push access to it; with that, they invoke the undocumented push options repo.private (toggle visibility) or repo.template (toggle template status) via 'git push -o repo.private=false/true' or '-o repo.template=false/true'. … Additional conditions and limiting factors are described in the full assessment.
Risk Assessment The supplied CVSS 3.1 vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:N (7.1) is internally consistent with the description: exploitation is remote over the Git protocol, low complexity, and requires low (but non-zero) privileges - specifically owner or admin-collaborator on the target repo. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in.
Exploit Scenario A contractor granted admin-collaborator access to a private repository runs 'git push -o repo.private=false' on a routine commit, silently making the repo public for a few minutes - long enough to clone or index proprietary source and CI/CD secrets - then pushes again with 'repo.private=true' to restore it. The GHSA advisory publishes the exact reproduction commands, so the attack requires no custom tooling; given the network Git attack vector and low complexity, only the pre-existing privileged access is needed.
Remediation Vendor-released patch: 1.27.0 - upgrade all Gitea instances to 1.27.0 or later, per GHSA-8p9h-49rc-qgxj (https://github.com/go-gitea/gitea/security/advisories/GHSA-8p9h-49rc-qgxj) and https://github.com/go-gitea/gitea/releases/tag/v1.27.0. … Detailed patch versions, workarounds, and compensating controls in full report.

Recommended ActionAI

Within 24 hours, identify all Gitea deployments and current versions; immediately audit repository access permissions to minimize administrative accounts and document baseline repository visibility settings. …

Sign in for detailed remediation steps and compensating controls.

Threat intelligence, references, and detailed analysis are available after sign-in.

More in Gitea

View all
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-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-2020-13246 HIGH POC
7.5 May 20

An issue was discovered in Gitea through 1.11.5. Rated high severity (CVSS 7.5), this vulnerability is remotely exploita

CVE-2022-0905 HIGH POC
7.1 Mar 10

Missing Authorization in GitHub repository go-gitea/gitea prior to 1.16.4. Rated high severity (CVSS 7.1), this vulnerab

CVE-2022-1058 MEDIUM POC
6.1 Mar 24

Open Redirect on login in GitHub repository go-gitea/gitea prior to 1.16.5. Rated medium severity (CVSS 6.1), this vulne

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-27780 CRITICAL
9.8 Jul 03

Branch-protection bypass in Gitea's self-hosted Git server (all versions before 1.26.0) allows a user with push access t

CVE-2026-26292 CRITICAL
9.8 Jul 03

Migration transport protections in Gitea are bypassed for Git LFS operations, affecting all self-hosted instances before

Share

CVE-2026-58437 vulnerability details – vuln.today

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