Gitea's diffpatch endpoint plants a Git hook, and the hook does the rest

CVE-2026-60004 turns repository write access into shell execution as the Gitea service account. The interesting part is not the injection — it is that Git hooks are executable files sitting inside a directory your developers write to all day.

CISA added CVE-2026-60004 to the Known Exploited Vulnerabilities catalogue on 25 August 2026, with a remediation due date of 28 August — a three-day window, which is how CISA signals that something is being used now rather than theoretically reachable.

The advisory describes it plainly:

Gitea contains a code injection vulnerability that allows an attacker with repository write access to send a malicious patch to the diffpatch API endpoint to plant an executable Git hook and run shell commands as the Gitea service account.

Everything worth saying about this bug is in the phrase plant an executable Git hook.

[object Object]1 — Attacker gets repository write accessa phished developer, a leaked CI token2 — Malicious patch to the diffpatch APIan ordinary authenticated request3 — Patch writes into hooks/ insteadTHE BUG: a path problem, not a parser one4 — Git runs the hook on the next pushno signing, no allowlist, no install step5 — Shell runs as the Gitea service accountreads every repo on the host, plus CI creds

Only step 3 is the vulnerability. Steps 4 and 5 are Git and the operating system behaving exactly as designed — which is why patching stops a new hook being written but does nothing about one planted earlier.

Why hooks are the payload

A Git repository carries a hooks/ directory. The files in it are ordinary executables, and Git runs them at defined moments — post-receive after a push lands, pre-commit before a commit is written, and a dozen others. There is no signing, no allowlist, and no separate "install" step. A file with the right name and the executable bit set is a hook.

That design is entirely reasonable for a tool that started life on a developer's own machine. It becomes a liability the moment the repository lives on a shared server running as a service account, because writing a file is now equivalent to scheduling code execution — and the scheduling is done by the server, on the server, at a moment the attacker can trigger.

So the vulnerability is not really "code injection" in the sense of a parser being fooled. It is a path problem: a patch that should only be able to modify tracked files is able to write into the repository's control directory instead. The execution afterwards is Git behaving exactly as documented.

"Requires write access" is not the mitigation it sounds like

The natural first reading is reassuring — an attacker needs write access, so this is an insider problem. It is worth resisting that reading.

Write access to at least one repository is the normal state of affairs for every developer, every contractor, and every CI token in the organisation. It is also the first thing an attacker obtains after phishing a developer or finding a personal access token in a build log. Treating repository write as a trust boundary assumes the boundary has not already been crossed, which is precisely the assumption an intrusion invalidates.

The useful framing is escalation: this bug converts write access to one repository into shell as the account that can read every repository on the host. On a self-hosted Gitea instance that account typically has the whole source estate, plus whatever credentials are sitting in CI configuration.

What to look for

None of the following is exotic, and none of it requires knowing the exploit. It follows from the mechanism.

File writes into hook directories. A hook being created or made executable outside of a deliberate administrative change is close to a zero-noise signal on a server. Watch for writes to any path matching */hooks/* under the Gitea data directory, particularly post-receive, post-update and pre-receive.

Process ancestry. The Gitea service spawning sh, bash, curl, wget or an interpreter is the observable consequence of a hook firing. Gitea legitimately executes git; it has far less business executing a shell that then makes an outbound connection. Alert on the Gitea service account as a parent of a shell whose child touches the network.

Outbound connections from the Git host. A source control server generally talks to a small, stable set of destinations. New egress from that host, especially immediately following a push, deserves attention.

Remediation

Patch — that is the actual answer, and CISA's due date has already passed. Beyond that, audit the hook directories on your instance rather than assuming they are clean, because a hook planted before patching survives the upgrade perfectly well. A patched Gitea will not let a new hook be written; it will run an old one without complaint.

Source: NVD — CVE-2026-60004 · CISA Known Exploited Vulnerabilities catalogue, added 25 August 2026.

This is analysis of a public advisory. It is not an incident report, and no intrusion data informed it — the detection guidance above is derived from the documented mechanism, not from observed activity.

Corrections and additions are welcome — this is a working document. Get in touch, or post a case of your own in the community.

Discussion

Guidelines

Sign in to comment. Corrections and additions are the point — this is a working document.