Skip to content
feed: live about
>_ 0dayNews
vendor advisory
● Breaking

Gitea CVE-2026-20896: Docker default trusts any X-WEBAUTH-USER — probing observed

The Gitea Docker image up through 1.26.2 shipped a wildcard reverse-proxy trusted list, collapsing auth to a header. Fixed in 1.26.3. The Hacker News reports opportunistic scanning 13 days after disclosure; ~6,200 exposed instances.

Marisol "Fuse" Delgado · Published · 5 min read

The Gitea Docker image shipped a bad default. Any request that reached the container could set an X-WEBAUTH-USER header and Gitea would trust it — no credentials, no prior session, no proxy actually terminating in front. The Hacker News reported opportunistic scanning against the flaw on 2026-07-06, 13 days after public disclosure, with roughly 6,200 internet-facing Gitea instances still reachable. CVE-2026-20896, CVSS 9.8, patched in Gitea 1.26.3. Reported by Ali Mustafa (@rz1027).

Here is what changed and what to do about it.

What is broken

Gitea supports reverse-proxy authentication: your front-end proxy authenticates the user, then passes the identity to Gitea in a header (X-WEBAUTH-USER by default). Gitea consults a trusted-proxy list before believing that header, so only requests from the real proxy get to bypass the login form. That is a normal, sensible pattern when the trusted list is set to the real proxy.

The Docker image’s default was REVERSE_PROXY_TRUSTED_PROXIES = * instead of the safe default 127.0.0.0/8,::1/128. A wildcard here means every source address is a trusted proxy, so every request is treated as though a real proxy authenticated it. An unauthenticated attacker who can reach the container over the network sets X-WEBAUTH-USER: whoever and Gitea logs them in as whoever. If whoever is admin, they are the admin.

The bug class is header trust with an over-broad trust boundary — the same shape as a lot of “proxy sniffing” and IP-spoofing auth bypasses across the industry. The Gitea core has always had a safe default. The Docker image shipped an unsafe one.

The Hacker News writeup is the going public source; I am not walking through the header sequence beyond what any admin needs to understand the risk. Read the article if you want the discoverer’s own framing.

What is confirmed exploited

Per The Hacker News, opportunistic probing against exposed Gitea instances began roughly 13 days after Ali Mustafa’s disclosure. The researcher cited in the piece characterized what has been seen so far as “initial investigation by the threat actor” — i.e. scanners and header probes checking who is still vulnerable, not full compromises confirmed in the same telemetry.

That is the honest read: this is the pre-mass-exploitation window on a public 9.8 with a working default-config bug. History says the window closes fast.

What is not confirmed as of this writing:

  • Named threat actor.
  • Confirmed post-exploitation from these probes — repo theft, credential harvest, secondary payload. Assume it is coming; do not assume it has not already happened on your box.
  • CISA KEV listing. Not present at time of publication. Check the KEV catalog directly.

Confidence is high enough on the probing to move on the patch today. It is not high enough to attribute or to publish an incident-victim count.

What Gitea changed

Gitea 1.26.3 (release notes) ships the Docker image with the correct default. If you rebuilt or pulled the image and did not override the trusted-proxy list yourself, you inherited the safe default automatically.

Two things worth flagging for anyone in the middle of a decision:

  • Version pinning. If your compose or Kubernetes manifest pins to gitea/gitea:1.26.2 or an older tag, docker pull does not silently fix this. You have to bump the pin.
  • Explicit overrides win. If your app.ini or environment already sets REVERSE_PROXY_TRUSTED_PROXIES explicitly, that value wins over the image default — safe or unsafe — regardless of image version. Check the config, not just the image tag.

What to do — in priority order

1. Bump every Gitea Docker deployment to 1.26.3 today.

Update the image tag, redeploy, verify. If your Gitea sits behind a real reverse proxy, this is a boring change. If you cannot bump this hour, the interim mitigation is to explicitly set REVERSE_PROXY_TRUSTED_PROXIES in your app.ini or environment to the actual proxy CIDR — usually 127.0.0.0/8,::1/128 for a sidecar or 10.x.x.x/24 (or your equivalent) for a dedicated proxy on the same subnet. That override survives image upgrades and closes the exposure regardless of which tag you run.

2. Take internet-facing Gitea off the public internet if you cannot patch or override this hour.

There are ~6,200 exposed instances per THN, and now there are opportunistic scanners walking that list. If yours is one of them and you cannot deploy the fix immediately, front it with an application firewall, a mesh VPN, or an SSH tunnel — anything that stops raw internet reaching the container port. This is a temporary measure, not a fix.

3. Hunt for exploitation on any exposed instance that ran 1.26.2 or older after 2026-06-23.

Approximate exposure window: the fix landed in Gitea 1.26.3 around 2026-06-23 (13 days before the 2026-07-06 THN piece). Any Docker deployment on 1.26.2 or older that was reachable from the internet during that window should be treated as potentially reached. Concrete pull for the IR team:

  • Gitea access logs for requests carrying an X-WEBAUTH-USER header from source IPs that are not your real proxy. This is the single highest-signal indicator — the legitimate proxy is one address (or one small CIDR); anything else setting that header is the exploit path.
  • Admin-user session activity from unfamiliar IPs, especially session establishments without a preceding password-auth or 2FA event in the Gitea audit log.
  • Repository read patterns: full clones or archive downloads of private repos from unfamiliar IPs, especially in short bursts. Repo theft is the natural payoff for this class of bug.
  • New SSH keys, personal access tokens, or webhooks added to admin or bot accounts in the exposure window — these are the persistence mechanisms an attacker plants for later access even after you patch.
  • Config or webhook changes to CI integrations. If Gitea webhooks fire your build system, tampering with them is a supply-chain foothold, not just a Gitea foothold.

Nothing exotic. It is the standard “assume compromise, prove it isn’t” pull, applied to a code-hosting tier that shouldn’t have unexplained header-auth traffic in the first place.

4. Rotate credentials and tokens on any instance where you cannot rule out header-auth abuse.

If your hunt turns up header-auth from anywhere but the real proxy, or if you can’t produce clean logs across the whole exposure window: rotate SSH deploy keys, personal access tokens, and webhook secrets on affected accounts. Repos already cloned by an attacker are not recallable, but every token and key rotated is one less pivot into your build systems and downstream deploys.

5. Do not rewrite your Docker-defaults policy over this one.

Bad defaults happen in upstream images regularly. Your job is to notice, patch, and log the response. If your image-refresh policy caught this in a week, that is your process working — don’t over-index. If it took longer, that is what to tighten, not the specifically Gitea-shaped fear.

Priority call

Bump every Gitea Docker deployment to 1.26.3 today, or set REVERSE_PROXY_TRUSTED_PROXIES to the actual proxy CIDR as an interim override. Take unpatched public instances behind a network gate if you cannot do either this hour. Then hunt the exposure window for header-auth from unexpected sources. Everything else on this list is worth doing only after those two are done.

Related coverage: our Adobe ColdFusion CVE-2026-48282 writeup is the other web-tier CVSS-9-plus this week worth checking your inventory against, and the GitLab ExifTool RCE CVE-2021-22205 revisit is a reminder that self-hosted code forges attract this treatment every time.

Sources

Found this useful? Share it.