Gitea's Docker Image Shipped a Dangerous Default, and It's Still Catching People
Gitea <=1.26.2 had a problem. The official Docker image set REVERSE_PROXY_TRUSTED_PROXIES=* by default, which means it trusted the X-WEBAUTH-USER header from any source. Ship it, run docker compose up, and your private repos were accessible to anyone who sent the right header.
CVE-2026-20896, CVSS 9.8. Caught in the wild within days of the PoC dropping.
What the actual vulnerability looks like
When Gitea runs behind a reverse proxy, it uses the X-WEBAUTH-USER header to identify the authenticated user — if your proxy passes it through. With REVERSE_PROXY_TRUSTED_PROXIES=*, Gitea accepts that header from any IP, not just your proxy. So:
curl -H "X-WEBAUTH-USER: admin" https://your-gitea.example.com/api/v1/repos
If your Gitea user is actually named admin — and a lot of them are — you just got read access to their private repos, no password needed.
That's it. No zero-day exploit chain, no stolen credentials. Just a header.
How to check if you're exposed
Look at how you start Gitea.
Docker Compose users:
environment:
- GITEA__server__PROXY_MODE=true
# Check if you have REVERSE_PROXY_TRUSTED_PROXIES set to *
Docker run:
docker run -e REVERSE_PROXY_TRUSTED_PROXIES=* gitea/gitea:1.26
If you see * anywhere in that config, you're trusting every IP that can reach your Gitea instance.
The second check: Who can actually reach your Gitea? If it's directly exposed to the internet (not behind a proper firewall or VPN-only access), that's the real problem. A wildcard proxy trust config on a publicly accessible instance is exactly as bad as it sounds.
The fix
Specify the actual IPs that are your reverse proxies. If your setup is a single Docker host with a reverse proxy on the same machine:
environment:
- GITEA__server__PROXY_MODE=true
- REVERSE_PROXY_TRUSTED_PROXIES=127.0.0.1
Or if your proxy is on a private network segment:
environment:
- REVERSE_PROXY_TRUSTED_PROXIES=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
You can also set this in app.ini directly under [server] if you prefer config files over environment variables.
The real issue
This isn't a Gitea bug — the code works correctly given proper configuration. It's a shipped default that made sense in a narrow self-hosted scenario (single host, no exposure) but catches anyone who deploys "as documented" without auditing the security implications.
The same class of issue shows up elsewhere: default credentials, open S3 buckets, debug endpoints on production. You're usually safe if your threat model includes "nobody tries to hit my services except through normal paths." That model breaks the moment something is internet-facing.
If you're running Gitea from the official Docker image, check your proxy trust config. It's a two-minute audit that might save you from an incident.
Schiff Heimlich | Sysadmin who has stopped being surprised by shipped defaults
Top comments (0)