Gitea Under Fire — Critical CVEs 2026

An RCE flaw with a public PoC, a Docker auth bypass under active exploitation, and five more fixes: everything operators of Gitea 1.25 and 1.26 need to know right now.
August 17, 2026 · CVE-2026-60004 · CVE-2026-58443 · CVE-2026-20896 · Security · Self-Hosting · Git
Action Required — CVE-2026-60004

Gitea 1.17 through 1.27.0 is affected by a critical RCE vulnerability (CVSS 9.8) with a public PoC. Instances with open registration are exploitable without any pre-existing credentials. Fix: upgrade to 1.27.1.

Multiple critical security vulnerabilities in Gitea have accumulated over summer 2026. The worst — CVE-2026-60004 — enables remote code execution via a crafted patch request and has had a public proof-of-concept since July 28, 2026. Anyone still running a version before 1.27.1 has a time-critical problem.

CVE Overview Since Version 1.25

CVE CVSS Description Fixed in Status (1.25.4)
CVE-2026-60004 9.8 RCE via Git Hook Injection (diffpatch) 1.27.1 Affected
CVE-2026-58443 9.6 Public-scope token pushes to private repos 1.27.0 Affected
CVE-2026-20896 9.8 Docker auth bypass via HTTP header 1.26.3 Docker + Reverse Proxy Auth only
CVE-2026-25779 6.1 Redirect bypass via backslash-encoded paths 1.25.5 Affected
CVE-2026-27660 5.4 Missing permission check on release drafts 1.25.5 Affected
CVE-2026-27657 6.5 User could change another user's primary email 1.25.5 Affected
CVE-2026-26232 5.9 OAuth2 authorization code: missing expiry/reuse check 1.25.5 Affected
CVE-2026-24690 5.4 Insufficient permission check for PR branch rebase 1.25.5 Affected

CVE-2026-60004 — Remote Code Execution (CVSS 9.8)

The most dangerous flaw lives in the diffpatch endpoint: Gitea processes repository patches using internal Git commands. Submitting the same specially crafted patch twice allows an attacker to plant a malicious Git hook inside a temporary bare clone — executing arbitrary shell commands as the Gitea service account.

No Prior Access Required

Gitea allows open registration by default (DISABLE_REGISTRATION = false). A completely external attacker can create an account, create a repository, and exploit the flaw immediately — with no pre-existing credentials. A public PoC has been available since July 28, 2026.

CVE-2026-58443 — Token Bypass for Private Repos (CVSS 9.6)

An API token issued with public-only scope can still push commits to private repositories. Access control does not apply in this case. A compromised public token therefore grants full write access to private codebases.

CVE-2026-20896 — Docker Auth Bypass via HTTP Header (CVSS 9.8)

The official Gitea Docker image shipped with REVERSE_PROXY_TRUSTED_PROXIES = * as its default. Any attacker could take over the admin account using a single X-WEBAUTH-USER: admin header — no password required. Active in-the-wild exploitation was observed 13 days after the advisory was published.

Prerequisite

CVE-2026-20896 only affects Docker deployments with reverse proxy authentication enabled (ENABLE_REVERSE_PROXY_AUTHENTICATION = true). Binary installations without this configuration are not affected.

Vulnerabilities Fixed in Gitea 1.25.5

Upgrading directly from 1.25.4 to 1.27.1 also includes all fixes from the March 1.25.5 release:

Immediate Mitigation (Before Upgrading)

If an immediate upgrade is not possible: disabling registration removes the primary attack vector for CVE-2026-60004 for attackers without an existing account.

# /etc/gitea/app.ini — [service] section
DISABLE_REGISTRATION = true

# Reload the Gitea service
systemctl reload gitea
Not a Full Fix

Disabling registration only removes the unauthenticated attack path. Any existing user with repository write access can still exploit CVE-2026-60004. Upgrading to 1.27.1 remains mandatory.

Upgrade to Gitea 1.27.1

The following steps apply to a binary installation on Linux with a systemd service. Total downtime is approximately five minutes.

1. Backup

# Stop the service
systemctl stop gitea

# Back up the SQLite database
cp /var/lib/gitea/data/gitea.db \
  /var/lib/gitea/data/gitea.db.bak-$(date +%Y%m%d)

# Back up the binary
cp /usr/local/bin/gitea /usr/local/bin/gitea.bak-1.25.4

# Back up the configuration
cp /etc/gitea/app.ini /etc/gitea/app.ini.bak-$(date +%Y%m%d)

2. Download and Verify Binary

wget -O /tmp/gitea-1.27.1-linux-amd64 \
  https://dl.gitea.com/gitea/1.27.1/gitea-1.27.1-linux-amd64

wget -O /tmp/gitea-1.27.1-linux-amd64.sha256 \
  https://dl.gitea.com/gitea/1.27.1/gitea-1.27.1-linux-amd64.sha256

# Verify checksum — must output "OK"
cd /tmp && sha256sum -c gitea-1.27.1-linux-amd64.sha256

3. Install and Run Database Migration

chmod +x /tmp/gitea-1.27.1-linux-amd64
mv /tmp/gitea-1.27.1-linux-amd64 /usr/local/bin/gitea

# Run DB migration before starting the service — important!
/usr/local/bin/gitea migrate --config /etc/gitea/app.ini

systemctl start gitea
Order Matters

gitea migrate must run before the service starts. If started first, Gitea may encounter missing database columns and crash.

4. Verify

# Check version
/usr/local/bin/gitea --version
# → Gitea version 1.27.1 ...

# Check service status
systemctl status gitea --no-pager
Rollback

If something goes wrong: stop the service, restore the backup binary (/usr/local/bin/gitea.bak-1.25.4), restore the database backup, start the service. SQLite makes this straightforward.

Sources