Gitea Shipped a 9.8 That Needs an Account. Gitea Also Ships With Anyone Being Able to Make One.
Updated: Aug 11
Gitea published the advisory for CVE-2026-60004 on July 28. Git hook injection, CVSS 9.8, remote code execution as the Gitea process. Everything from 1.17 up to 1.27.1 is affected. The fix merged and was backported on July 26, 1.27.1 shipped on July 27, the advisory followed on the 28th. Found and reported by Shai Rod, who publishes as NightRang3r.
The scoring says it needs authentication and repository write permission. That sounds like a meaningful barrier until you remember what a default Gitea install does: open registration is on. An outside visitor creates an account, creates a repository, and now holds write permission on a repository. The precondition satisfies itself.
On an unchanged install this is an unauthenticated remote code execution with two extra HTTP requests in front of it.
Three proof-of-concepts in thirty-eight hours
Our exploit harvester watches public repositories for exploit code appearing against known CVEs. Here is what it recorded, with GitHub's own repository creation times:
HORKimhab/[CVE-2026-60004](https://analytics.dugganusa.com/api/v1/dredd/kev-gap?cve=CVE-2026-60004) — repository created 08:35:16 UTC on July 29, indexed by us at 12:00:56 UTC the same day. That is roughly a day after the advisory. The detection rules we pulled out of it target the Gitea API surface: the version endpoint, the user endpoint, the user repositories endpoint, and a shell invocation as the payload stage.
EQSTLab/[CVE-2026-60004](https://analytics.dugganusa.com/api/v1/dredd/kev-gap?cve=CVE-2026-60004) — created 08:19:19 UTC on July 30, indexed at 12:00:44 UTC. This one is more complete, and its detection rules name the actual mechanism: the post-index-change hook path, and a marker file written to a predictable location to prove execution.
0xBlackash/[CVE-2026-60004](https://analytics.dugganusa.com/api/v1/dredd/kev-gap?cve=CVE-2026-60004) — created 22:24:16 UTC on July 30, indexed at 00:00:44 UTC on July 31. Broader API enumeration than the first, including the per-repository endpoint pattern.
Three independent people, three separate repositories, inside thirty-eight hours of the advisory. Nobody coordinated that. It is simply what a 9.8 in widely self-hosted software looks like when the fix diff is public and the precondition is trivially met.
The second and third of those did not need to do original work. The first one existed. That is the shape of weaponisation — the expensive version happens once, and then it gets cheaper for everyone who follows.
The thing self-hosting quietly costs you
Gitea's appeal is that it is the small, fast, self-hostable alternative to the large forge. That is a genuinely good thing and we are not arguing against it. But the trade is real and it lands exactly here.
A hosted forge patches this for you before you read about it. A self-hosted forge patches when you patch it. And the population running Gitea skews toward the people this blog exists for — small teams, universities, municipalities, homelabs that grew into production, shops that self-host precisely because they do not have the budget for the alternative. That population has the same 9.8 and materially less staff to act on it.
It also skews toward instances that were stood up once, worked, and were never revisited. Open registration is on because nobody turned it off. That was fine for three years. It stopped being fine on July 28.
And a forge is not an ordinary application. Code execution on it is code execution next to your source, your CI runners, and whatever deploy credentials your pipeline holds. It is the same argument we made about the TeamCity bug this week: the machine that builds and stores what you ship is not a website, and compromising it does not produce a breach, it produces a supply chain.
We have been on this thread since July
This is not the first Gitea bug we have tracked this month, and our own record has something the advisory does not.
CVE-2026-20896, the Gitea Docker flaw, has been in our harvester since July 3. Four separate exploit repositories against it, spread across four weeks: one created July 2, another July 5, another July 16, and a fourth — from EQSTLab, the same group that published for 60004 — created July 29 and indexed by us on July 30. Reporting this week says threat actors began probing 20896 in the wild roughly thirteen days after disclosure.
That is a useful curve to hold next to 60004. For 20896, exploit code kept arriving for four weeks after the first drop, and real-world probing showed up almost two weeks in. Nobody stopped writing exploits because the bug was old news. If 60004 follows the same shape — and a higher-severity bug with an easier precondition has no reason to follow a slower one — the exploit ecosystem around it is going to keep growing for the next month, and the probing has not started yet.
We should be straight about one limit: our edge sees no probes for either of these against us. We checked. Nothing in our decision logs for Gitea API paths or hook endpoints. That is a real absence, not a comforting one — it means we are telling you about exploit code that exists, not attacks we have caught, and it means you are still standing in the cheap part of the timeline.
What to do tonight
Upgrade to 1.27.1. That is the fix and there is no partial substitute for it.
Turn off open registration while you are there, and then leave it off. It does not fix the bug — anyone who already has write access to any repository on your instance can still reach it — but it removes the path that turns an authenticated bug into an unauthenticated one, and on most private instances open registration was never wanted in the first place.
If your instance was internet-reachable on an affected version with open registration on, do not stop at the upgrade. Enumerate accounts created since July 28 and look at any you cannot account for. Look at the git hooks configured on your repositories, since that is where the payload lives and it survives a restart. Then rotate what the Gitea process could reach: deploy keys, CI tokens, registry credentials, webhook secrets.
The honest position
We did not find this. NightRang3r found it and Gitea shipped the fix before the advisory, which is the order you want.
What we contribute is the timeline, measured on our own instruments: three public exploit repositories inside thirty-eight hours, timestamps from GitHub as read by our harvester, plus four weeks of the same pattern on the previous Gitea bug for comparison. That is a first-party observation, not a re-telling of somebody else's feed, and it is the part that tells a defender how much time they actually have rather than how much they were promised.
Confidence capped at 95%. Version ranges and severity are from the Gitea advisory and the CVE record. Repository creation times are GitHub's. The absence of probing against our own edge is a point-in-time observation from tonight and is designed to expire — when it does, that will be its own post.
Every indicator in this post is in the feed. Free.
1.58M+ IOCs, STIX 2.1 / TAXII, 88% novel vs ThreatFox, exploited-CVE leads ahead of CISA. No credit card — a free API key in 30 seconds, and you can audit every claim above against the live endpoints.
Was this useful? Thirty seconds, no cookies, no tracking, no third parties, your address hashed and never stored. If the box below does not load, the same question lives at https://analytics.dugganusa.com/nps.html?post=gitea-shipped-a-9-8-that-needs-an-account-gitea-also-ships-with-anyone-being-able-to-make-one




Comments