CVE-2026-79960 Overview
CVE-2026-79960 is an authorization flaw in Gitea where push operations authenticated with a deploy key were incorrectly attributed to the repository owner. The push hook pipeline evaluated permissions against the owner instead of the deploy key itself. A holder of a writable deploy key could create protected tags without being on the tag allow list. The same flaw allowed changing repository visibility through push options, including flipping a private repository to public. Pull requests submitted through the AGit flow with a deploy key were also attributed to the owner. The weakness is classified under CWE-863: Incorrect Authorization.
Critical Impact
A writable deploy key can bypass tag protection rules and change repository visibility, exposing private source code to unauthorized viewers.
Affected Products
- Gitea self-hosted Git service
- Gitea versions prior to v28.0.0
- Repositories configured with writable deploy keys
Discovery Timeline
- 2026-10-06 - CVE-2026-79960 published to the National Vulnerability Database
- 2026-10-07 - Last updated in NVD database
Technical Details for CVE-2026-79960
Vulnerability Analysis
The flaw sits in Gitea's push hook pipeline. When a client authenticated with a deploy key, the server recorded the repository owner as the pusher identity. Downstream permission checks then evaluated the owner's privileges rather than the deploy key's scope. Because repository owners generally hold full administrative rights, every subsequent authorization decision in the hook pipeline passed. The result is an impersonation condition that converts a scoped credential into an owner-equivalent credential for specific push-time operations.
Two concrete abuse paths were documented in the vendor advisory. First, a holder of a writable deploy key could push protected tags even when the deploy key identity was absent from the tag allow list. Second, the same actor could send push options that toggle repository visibility, including making a private repository public. A third issue surfaces in the AGit flow, where pull requests opened with a deploy key were attributed to the owner, producing a false audit trail.
Root Cause
The root cause is identity substitution during push processing. Gitea needed to carry the deploy key as the acting principal through the hook pipeline, but it substituted the repository owner before authorization checks ran. This is a classic CWE-863 condition where the wrong subject is evaluated against the policy.
Attack Vector
The attack requires network access to the Gitea instance and possession of a writable deploy key for the target repository. No end-user interaction is needed. The attacker performs a normal git push over SSH or HTTPS and either targets a protected tag reference or appends push options that change repository settings. See the GitHub Security Advisory GHSA-7769-9pr9-m24h and the upstream fix in Pull Request #37306 for the specific code paths.
Detection Methods for CVE-2026-79960
Indicators of Compromise
- Protected tag creation events where the acting principal is a deploy key not present in the tag allow list.
- Repository visibility changes from private to public immediately following a push from a deploy key session.
- Pull requests opened through the AGit flow whose author matches the repository owner but originate from a deploy key session.
Detection Strategies
- Correlate Gitea audit logs with SSH authentication events to confirm whether a git push was keyed to a user credential or a deploy key.
- Alert on repo.visibility transitions and protected-tag writes that occur within the same session as deploy key authentication.
- Baseline deploy key usage per repository and flag any push that invokes push options affecting repository settings.
Monitoring Recommendations
- Forward Gitea application logs, SSH daemon logs, and reverse proxy access logs to a central analytics tier for joined queries.
- Monitor the Gitea admin API for unexpected changes to repository visibility and branch or tag protection rules.
- Review deploy key inventories on a recurring cadence and remove writable keys that no longer require push access.
How to Mitigate CVE-2026-79960
Immediate Actions Required
- Upgrade Gitea to v28.0.0 or later, which includes the fix shipped in Pull Request #37306.
- Audit every repository for writable deploy keys and downgrade non-essential keys to read-only.
- Review recent protected-tag creations and private-to-public visibility changes for unauthorized activity.
Patch Information
The vendor shipped the fix in Gitea v28.0.0. Release details are documented in the Gitea Blog Release Announcement and the Gitea Release v28.0.0 notes. The code change carries the deploy key as the acting principal through the push hook pipeline so authorization checks evaluate the correct subject.
Workarounds
- Convert writable deploy keys to read-only until the upgrade is deployed, which prevents the push paths that trigger the bypass.
- Disable push options at the server level if the deployment does not require them, blocking the visibility-change vector.
- Restrict tag protection rules so that only trusted user accounts, not deploy keys, can produce the protected ref patterns in use.
# Configuration example: audit and remove writable deploy keys via the Gitea API
# Replace TOKEN, HOST, OWNER, and REPO with environment values.
curl -s -H "Authorization: token TOKEN" \
"https://HOST/api/v1/repos/OWNER/REPO/keys" \
| jq '.[] | select(.read_only == false) | {id, title, key}'
# Delete a specific writable deploy key by id
curl -X DELETE -H "Authorization: token TOKEN" \
"https://HOST/api/v1/repos/OWNER/REPO/keys/KEY_ID"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.