Kai Ole Hartwig
8 min read
Critical

Gitea Docker images: CVE-2026-20896 — one HTTP header is enough for admin access, now actively scanned

Gitea operators running the official Docker image with reverse-proxy authentication enabled should look now: CVE-2026-20896 (GHSA-f75j-4cw6-rmx4) sits in a hardcoded REVERSE_PROXY_TRUSTED_PROXIES = * in the Docker templates — the application trusts the X-WEBAUTH-USER header from any source, not just the actual proxy. A single crafted header is enough to impersonate any user, admins included. CVSS 3.1 sits at 9.8 (critical). Since 7 July 2026, Sysdig has observed active scanning against unpatched instances — this is no longer a theoretical risk.

TL;DR — 90 seconds

Affected?

Gitea instances built from the official Docker image (docker/root and docker/rootless), version 1.26.2 and earlier, with ENABLE_REVERSE_PROXY_AUTHENTICATION = true. Binary installs following app.example.ini are not affected.

Risk?

Unauthenticated privilege escalation to admin via X-WEBAUTH-USER header spoofing. CVSS 3.1 9.8 (critical) — network, no auth, no interaction required.

Immediate action?

Upgrade to Gitea 1.26.4 (press reports say 1.26.3 has a regression — target 1.26.4 directly), or, if an update isn't immediately possible, manually set REVERSE_PROXY_TRUSTED_PROXIES to 127.0.0.0/8,::1/128.

Recommendation?

Patch today, not this week: actively scanned since 7 July 2026 (Sysdig), ~6,200 instances potentially reachable per a Shodan query (the actual number of vulnerable instances is unconfirmed).

Criticality?

critical (hero badge) — full unauthenticated admin takeover given direct access to the container port.

What is the problem?

Gitea supports reverse-proxy authentication: an upstream proxy handles the actual login and passes the verified identity to the application via an HTTP header (X-WEBAUTH-USER). For this to be safe, Gitea must only trust that header when the request genuinely comes from the proxy — controlled via REVERSE_PROXY_TRUSTED_PROXIES. The documented safe default is loopback-only (127.0.0.0/8,::1/128).

That exact default is set wrong in the official Docker image templates: docker/root/etc/templates/app.ini (line 55) and the corresponding rootless variant (line 52) hardcode REVERSE_PROXY_TRUSTED_PROXIES = * instead — a wildcard that treats every source address as trusted. With ENABLE_REVERSE_PROXY_AUTHENTICATION enabled (common in reverse-proxied deployments), a self-set X-WEBAUTH-USER header from any source is enough to impersonate the named user — admin accounts included. Security researcher Ali Mustafa, who reported the flaw, put it plainly: any process that can reach the container's HTTP port directly can impersonate any user, regardless of whether the instance is publicly reachable or “only” internal.

Important context: binary installs following the official app.example.ini are not affected by this finding — the problem is confined to the Docker image templates.

Who is affected?

AffectedNot affectedConditions
Gitea from the official Docker image (docker/root + docker/rootless), version ≤ 1.26.2Binary installs following app.example.iniENABLE_REVERSE_PROXY_AUTHENTICATION = true must be active
Deployments without an explicit override of REVERSE_PROXY_TRUSTED_PROXIESInstances with REVERSE_PROXY_TRUSTED_PROXIES correctly set to loopback/proxy IPAttacker needs access to the container's HTTP port — public or internal is enough
Gitea versions up to 1.26.2Gitea 1.26.4 and newer1.26.3 reportedly has a regression (Tech Times) — target 1.26.4, don't stop at 1.26.3

A Shodan query shows roughly 6,200 Gitea instances that are generally internet-reachable; how many of those actually run the vulnerable Docker image and configuration is not established by that number — only the rough attack surface.

Impact

Successful exploitation means full identity takeover, not just read access: spoofing an admin via the header grants access to all repositories including private ones, visibility into CI/CD secrets stored in repository or organization variables, the ability to push commits to protected branches, tamper with CI pipelines, and create or delete user accounts. Because self-hosted git servers like Gitea typically bundle both source code and deployment secrets, this finding is a multiplier for downstream supply-chain risk: a compromised Gitea instance is a plausible starting point for compromised downstream artifacts.

Exploitation requires no authentication and no user interaction — only network access to the container's HTTP port. That's the core of the CVSS 3.1 score of 9.8.

Mitigation / immediate steps

Note: the following steps are my operational take based on GHSA-f75j-4cw6-rmx4 and the cited reporting — not a vendor-certified guide. Reconcile concrete version levels against the Gitea advisory.

Operational decision block

Step 1 — upgrade to 1.26.4

 

# check current version
docker exec <gitea-container> gitea --version
# pull the patched image (1.26.4 — 1.26.3 reportedly has a regression)
docker pull gitea/gitea:1.26.4
docker compose up -d gitea

 

Step 2 — until patched, restrict trusted proxies manually

 

# in app.ini (volume mount or docker exec into the container):
[security]
REVERSE_PROXY_TRUSTED_PROXIES = 127.0.0.0/8,::1/128
# restart
docker restart <gitea-container>

 

Step 3 — harden the network

 

# don't expose the container's HTTP port directly — only the reverse proxy should reach it
# check docker-compose.yml for 0.0.0.0 bindings that bypass the proxy
# on Kubernetes: NetworkPolicy restricting the pod's port to ingress/proxy only

 

Step 4 — if not needed, disable reverse-proxy auth

 

[service]
ENABLE_REVERSE_PROXY_AUTHENTICATION = false

Detection / verification

Check points derived from the advisory and common Docker/log practice.

Version & config check

 

docker exec <gitea-container> gitea --version
docker exec <gitea-container> grep -A3 "\[security\]" /data/gitea/conf/app.ini | grep -i trusted_proxies
docker exec <gitea-container> grep -i enable_reverse_proxy /data/gitea/conf/app.ini

 

Check logs for header spoofing

 

# X-WEBAUTH-USER from sources outside the expected proxy IP in the access log?
grep -i "x-webauth-user" /path/to/reverse-proxy/access.log | awk '{print $1}' | sort -u

 

Check the admin list for unknown accounts

 

curl -s -H "Authorization: token <admin-token>" \
  gitea.example.com/api/v1/admin/users | jq '.[] | select(.is_admin==true) | .login'

 

Runtime indicators

 

- new/unknown admin accounts
- unexpected commits on protected branches
- CI/CD pipeline changes outside known deploy windows
- X-WEBAUTH-USER headers on requests not originating from the configured proxy

Operator guidance

Mid-market

Patch to 1.26.4 this week — Gitea instances typically bundle source code and CI secrets, which turns this finding into a lever for downstream incidents. Check in parallel whether REVERSE_PROXY_TRUSTED_PROXIES was ever explicitly set; if not, your instance has likely been exposed since the Docker image was built.

Enterprise

Additionally: audit container network exposure — is the HTTP port reachable beyond the intended proxy hop? Internal segmentation matters here since the finding doesn't require public exposure. Reconcile SBOM/inventory for which internal systems have direct network access to Gitea containers.

Kubernetes

Check the NetworkPolicy restricting access to the Gitea pod's HTTP port to ingress/proxy only; audit Service type (avoid NodePort/LoadBalancer exposing the raw port); update the image pin to 1.26.4 in Helm values/manifests.

Decision block

Act today if: Docker image + reverse-proxy auth active + REVERSE_PROXY_TRUSTED_PROXIES unchecked. Monitor if: binary install with the documented safe default.

Frequently asked questions about CVE-2026-20896

Wie viele Instanzen sind laut aktuellen Berichten betroffen?+

Eine Shodan-Abfrage zeigt rund 6.200 grundsätzlich internetseitig erreichbare Gitea-Instanzen (Stand Anfang Juli 2026) — wie viele davon tatsächlich die verwundbare Docker-Konfiguration fahren, ist damit nicht belegt, nur die grobe Angriffsfläche.

Wie erkenne ich, ob meine Instanz bereits angegriffen wurde?+

Prüfen Sie die Admin-Nutzerliste auf unbekannte Accounts, Reverse-Proxy-Logs auf X-WEBAUTH-USER-Header von unerwarteten Quell-IPs, und die Commit-Historie geschützter Branches auf unerklärte Änderungen — siehe Detection-Abschnitt oben.

Sind Binärinstallationen betroffen?+

Nein, laut Advisory betrifft der Fund ausschliesslich die offiziellen Docker-Image-Vorlagen. Binärinstallationen, die der Standard-app.example.ini folgen, verwenden den sicheren Loopback-Default.

Was, wenn ich Reverse-Proxy-Authentifizierung gar nicht nutze?+

Dann ist dieser konkrete Ausnutzungspfad (ENABLE_REVERSE_PROXY_AUTHENTICATION = true) nicht aktiv. Trotzdem lohnt sich das Update, da REVERSE_PROXY_TRUSTED_PROXIES = * als Fehlkonfiguration im Image bleibt, falls die Funktion später aktiviert wird.

Reicht ein Upgrade auf 1.26.3?+

Laut Presseberichten (Tech Times) soll 1.26.3 eine Regression enthalten — die aktuelle Empfehlung lautet, direkt auf 1.26.4 zu aktualisieren. Prüfen Sie die offizielle Gitea-Release-Notes vor dem Rollout.

Bin ich betroffen, wenn Gitea nicht öffentlich erreichbar ist?+

Möglicherweise trotzdem — der Angriff erfordert nur Zugriff auf den Container-HTTP-Port, nicht zwingend aus dem Internet. Interner Netzzugriff (z. B. von einem kompromittierten Nachbarsystem im selben Netzsegment) reicht laut Advisory aus.

Conclusion

CVE-2026-20896 is a textbook case of a single wrong default in a distribution template — not the application code itself — becoming unauthenticated admin takeover. The fix is straightforward (an update or one line of config), but exploitation is trivial and has been actively observed since 7 July 2026. Anyone running Gitea from the official Docker image with reverse-proxy auth enabled should check REVERSE_PROXY_TRUSTED_PROXIES today — regardless of whether the instance is publicly reachable.

Sources

I patch, harden and monitor your Gitea/Forgejo instance — Docker config audit, network segmentation and CI secret rotation included.

Version and config audit of your Gitea Docker deployments, hardening of REVERSE_PROXY_TRUSTED_PROXIES and network access, rotation of potentially exposed CI/CD secrets, plus a look at adjacent self-hosted git risks.

Platform operations instead of advice on paper: I check, patch and validate production Gitea instances — from config to network segmentation.

About the author

[Translate to English:] Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Freelance DevSecOps consultant · OnlyOle Consulting

Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.

TeamPCP, GitHub breach May 2026, BreachForum listing, supply chain security, TanStack Shai-Hulud, VS Code extension suspicion

TeamPCP lists ~4,000 GitHub-internal repositories

On 19 May 2026 the group TeamPCP listed roughly 4,000 GitHub-internal repositories for sale on BreachForum. GitHub is investigating but has not labelled the incident a confirmed breach — customer data outside the internal repos is, by GitHub's current statement, not affected. What we know, what we don't, and what mid-sized companies should still do today.

GitLab, CVE-2026-6552, CVE-2026-10087, CVE-2026-7250, CVE-2026-9204, patch release, 19.0.2, 18.11.5, 18.10.8, Group SAML, account takeover, XSS, Analytics Dashboard, Grape API DoS, Gitaly SSRF, self-managed, CI/CD, DevSecOps, supply chain

GitLab patch release (CVE-2026-6552/10087)

Scheduled GitLab batch patch release (10 June 2026): twelve fixes, four High. The headline is two CVSS 8.7 Enterprise Edition flaws — CVE-2026-6552 (account takeover via the Group SAML identity API, owner precondition) and CVE-2026-10087 (XSS in the Analytics Dashboard). Plus CVE-2026-7250 (unauthenticated DoS in the Grape API, CE/EE) and CVE-2026-9204 (SSRF in the Gitaly repository import, CE/EE). Only self-managed below 18.10.8 / 18.11.5 / 19.0.2 is affected; GitLab.com and Dedicated are covered. A CI/CD hub holds code and secrets at once — patch cadence is supply-chain security.