CISA Gave Federal Agencies Until Tomorrow to Patch Gitea. The Attack in the Wild Took Eleven Seconds.
CISA added CVE-2026-60004 to its Known Exploited Vulnerabilities catalog on August 25 and ordered federal civilian agencies to fix it by August 28. It is a 9.8, it is in Gitea, and it is being exploited right now. If you self-host your Git, this is the one thing worth doing before the weekend.
The mechanism is short enough to state in one sentence: an attacker with ordinary write access to a repository sends a crafted patch to Gitea's diffpatch endpoint, which plants an executable Git hook, which runs arbitrary shell commands as the Gitea service account. The maintainers' own advisory adds the sentence that turns this from an insider risk into an internet risk. "With open registration enabled, the attack can be performed by an unauthenticated visitor after registering a normal account and creating a repository."
Why this one is worse than its CVSS score suggests
Nine point eight is already close to the ceiling, so "worse than the score" needs justifying. Three things do it.
The precondition is not a precondition for most people. "Requires repository write access" reads like a meaningful barrier until you remember that self-hosted Gitea instances are frequently stood up with open registration on, because that is how you let collaborators join without emailing you. On those instances the attacker supplies their own write access in one HTTP request.
The published advisory shipped with a working proof of concept. The disclosure to maintainers was private, but the advisory that followed included the exploit, which is why the gap between patch and mass scanning was measured in weeks rather than months.
And the blast radius is credential-shaped. Depending on how the Gitea process is isolated, successful exploitation can reach the main config file, application and process-environment secrets, database credentials and contents, and OAuth and integration credentials. A Git server is where you keep the keys to everything else. That is the whole point of it.
The incident report is the most useful thing published this week
A developer posted a detailed writeup on Habr after their organisation's self-hosted instance was compromised. It reads like a case study written specifically for people who run one server.
Their hoster alerted them that the virtual server's CPU had been pinned for a long time. That is how they found out, not from a log, not from an alert they had configured. The instance was on an outdated Gitea version with open registration, no email confirmation, and no CAPTCHA. An automated scanner registered an account, created a repository, and triggered the chain. The payload wrote a proof of RCE back into a Git branch, then pulled down a shell loader, then a crypto-miner-shaped dropper that started fighting the box for CPU.
The active phase of the attack took about eleven seconds. There is no monitoring setup a solo operator plausibly runs that catches an eleven-second window in real time. Which means the honest defence here is not detection, it is configuration.
The thing that saved them was Docker. Gitea was running in an unprivileged container, so the code landed inside the container rather than on the host, and the miner did not survive a restart. The investigation found no persistence via cron, systemd, or new SSH keys. Their remediation was upgrade to 1.27.2, disable open registration, remove the extra signup methods, rotate every secret and token, tighten Docker networking, and block outbound internet from the container.
That last one is the item most people skip and the one I would keep.
The checklist
Patch first. The fix landed in Gitea 1.27.1 in late July. 1.27.2 is current, and that is the version the compromised operator upgraded to. If you are on anything older than 1.27.1, you are exposed today.
Then work through the configuration, in this order:
# 1. What version am I actually running? docker exec -it gitea gitea --version # 2. Is open registration on? Check app.ini: # [service] # DISABLE_REGISTRATION = true # REQUIRE_SIGNIN_VIEW = true grep -A5 '^\[service\]' /path/to/gitea/conf/app.ini # 3. Who has accounts, and did any of them appear recently? # Site Administration -> User Accounts, sort by created date. # 4. Does the container have outbound internet it does not need? docker exec -it gitea sh -c 'wget -qO- -T3 https://example.com >/dev/null && echo REACHABLE || echo blocked'
If you find an account you did not create, or a repository you do not recognise, assume the secrets in that config file are gone and rotate them. Not "consider rotating." Rotate. The whole value of the attack is the credential harvest, and rotating a Gitea instance's tokens is an hour of annoyance against an unbounded downside.
If your Gitea is running directly on the host rather than in a container, the Habr writeup is the argument for changing that. The container is what turned a full compromise into a restart.
The part nobody writes down
Self-hosted Git is the most common piece of real infrastructure a solo operator owns. It gets set up in one focused afternoon, it works, and then it never gets touched again because it is not the product. My own Gitea has been running unattended for long enough that I had to go look up how I deployed it before I could check the version, which is not a flattering thing to admit in public.
The fix for that is not discipline, because discipline does not survive contact with a launch week. It is a calendar entry. Mine is now the first Saturday of the month, fifteen minutes, check versions on the three things I self-host and read their release notes. That is a lower bar than "stay on top of security" and it would have caught this one with weeks to spare.
Where this could be overblown
The reasonable pushback: if your Gitea is behind a VPN or a Tailscale network, not exposed to the public internet, and has registration disabled, your actual risk here is close to zero and the KEV listing does not apply to you in any meaningful way. That is true, and if that describes your setup you can patch on your normal schedule and go do something more useful with your Saturday.
The second piece of pushback is that the observed exploitation is crypto-mining, which is the least sophisticated outcome available and did not even survive a container restart. Nobody has published evidence of targeted attacks against small self-hosted instances for their credentials. That could change, and the credential exposure is what makes it worth patching, but the honest current state is opportunistic scanning for CPU rather than anyone coming for your OAuth tokens specifically.
Author
Lukas
@lukcombinator