Gitea under active exploitation: CVE-2026-60004
On 25 August 2026, CISA added CVE-2026-60004 to the Known Exploited Vulnerabilities catalog. The flaw affects Gitea, the self-hosted Git service many engineering organisations run as a lighter alternative to hosted forges. According to the KEV entry, an attacker with repository write access can send a malicious patch to the diffpatch API endpoint, plant an executable Git hook, and run shell commands as the Gitea service account. That is code execution on your source-of-truth server.
This post covers what the flaw is, why CISA judged it exploited rather than theoretical, how to check whether your estate is affected, and what to do inside the federal remediation deadline. It also covers the nine other KEV additions from the same week, because several share blast radius with a Gitea deployment.
What CVE-2026-60004 is
CISA describes CVE-2026-60004 as a code injection vulnerability in Gitea. The exploitation chain, as summarised in the KEV entry, has three ingredients:
- The attacker holds write access to at least one repository on the target Gitea instance.
- They submit a crafted patch through the
diffpatchAPI endpoint. - Gitea processes the patch in a way that lets the attacker plant an executable Git hook, which then runs shell commands as the Gitea service account.
Git hooks are ordinary executables that Git invokes on repository events (post-receive, update, and so on). If an attacker can write to hooks/ inside a bare repository and mark the file executable, Git runs it the next time the corresponding event fires. The diff-and-patch code path is coerced into writing attacker-controlled content to a path that Git treats as trusted.
The authenticated precondition matters for defenders. This is not a drive-by against your public login page; it requires a principal with repository write access. That constraint does not make the finding minor:
- Any compromised developer credential or leaked personal access token becomes a stepping stone to full code execution on the Gitea host.
- Many Gitea deployments accept self-service sign-up on internal networks, then rely on repository ACLs. A low-privilege user with write on a single sandbox repository is enough.
- CI service accounts frequently hold write access for tag pushes or release branches. Those tokens are prime pivot points.
Why CISA judged it actively exploited
CISA adds a CVE to KEV only when it has reliable evidence of exploitation in the wild against real targets. The catalog is not a severity ranking or a CVSS re-scoring exercise. When a CVE moves onto KEV, federal civilian agencies are bound by Binding Operational Directive 22-01 to remediate inside a set deadline, typically two to three weeks. That deadline is the practical signal to defenders: actors are already using this, and carrying the exposure past the deadline is a policy failure, not a risk-acceptance decision.
The Gitea entry names the code path (diffpatch API), the attacker precondition (repository write), and the outcome (shell as the Gitea service account) in the KEV description itself. That specificity is unusual and useful; it means the detection surface is well defined.
Are you affected? A five-minute triage
Run this triage before touching the upgrade path. It targets the on-call engineer with no prior Gitea internals exposure.
# 1. Inventory: is Gitea running here at all?
systemctl list-units --type=service --state=running | grep -i gitea
ps -eo pid,user,cmd | grep -i '[g]itea'
# 2. Version and config
sudo -u git /usr/local/bin/gitea --version
sudo -u git /usr/local/bin/gitea --config /etc/gitea/app.ini manager show-config \
| grep -iE 'run_user|repo_root|http_addr|http_port'
# 3. Which service account owns the process?
# Any hook the attacker plants runs as this user.
id "$(ps -o user= -p "$(pgrep -f 'gitea web')" | head -n1)"
# 4. Look for unexpected hooks under bare repositories
REPO_ROOT=$(sudo -u git /usr/local/bin/gitea --config /etc/gitea/app.ini \
manager show-config | awk -F= '/^ROOT/ {gsub(/ /,"",$2); print $2; exit}')
sudo find "$REPO_ROOT" -type f -path '*/hooks/*' \
! -name '*.sample' -perm -u+x -printf '%TY-%Tm-%Td %p\n' \
| sort
Read the last command's output carefully. Legitimate Gitea deployments do place hook wrappers in hooks/, but they are stable and version-controlled by Gitea itself. A recently modified, executable hook that is not a vendor-shipped wrapper is a candidate indicator of exploitation. Preserve the file, capture its owner, mtime, and hash, and treat the host as suspect before you patch over the evidence.
For log-side triage, look for HTTP POSTs to endpoints containing diffpatch, correlated by source IP and authenticated user. Unusual patch submissions from CI tokens or from users who rarely open pull requests are the signal you want.
What to do inside the deadline
Order of operations for a KEV-driven response:
- Patch first, forensicate second, but preserve evidence. Snapshot the VM or take a filesystem image of
REPO_ROOTbefore upgrading if the hook sweep returned any hits. - Upgrade Gitea to a fixed release per the vendor advisory linked from the CVE record. Do not backport patches by hand into an older build.
- Rotate every credential that could reach a write-capable repository. That includes personal access tokens, deploy keys, SSH keys stored on runners, and OAuth applications. Treat any credential the Gitea database has seen as burned if you found a planted hook.
- Constrain the service account. The blast radius of this vulnerability is defined by what the Gitea user can do on the host. Run Gitea under a dedicated system user, deny it a login shell, and apply systemd hardening (
ProtectSystem=strict,NoNewPrivileges=yes,PrivateTmp=yes). - Turn off self-service sign-up on any Gitea instance reachable from untrusted networks until you are on a fixed version. It closes the cheapest path to the repository-write precondition.
- Add a detection. Alert on any write to
/hooks/underREPO_ROOTthat the Gitea process did not perform, or on file-mode changes that set the executable bit on files in that path.
The rest of the week matters too
CVE-2026-60004 did not land alone. In the seven days prior, CISA added nine other CVEs across enterprise infrastructure: Oracle HTTP Server and WebLogic Proxy Plug-in (CVE-2026-21962), Zimbra Collaboration Suite (CVE-2026-73570, unauthenticated OS command injection via SMTP), TrueConf Server (CVE-2026-72530 and CVE-2026-72529, both reachable on TCP/4307), MLflow (CVE-2026-64849, SSRF into cloud metadata), Apple macOS Screen Sharing (CVE-2026-65400), Broadcom VMware vCenter (CVE-2026-59310, path traversal to RCE), Microsoft SharePoint (CVE-2026-55040), and Microsoft IKE Service Extensions (CVE-2026-33824, a double free with RCE potential).
Two of these compound the developer-platform blast radius. MLflow's SSRF (CVE-2026-64849) can retrieve response bodies from cloud metadata services on the same subnet where Gitea and CI runners often live, providing a fast path to instance credentials. The Zimbra command injection (CVE-2026-73570) is unauthenticated over SMTP: any internet-exposed ZCS host is a foothold candidate with line-of-sight to your internal Git server.
Treat this week's KEV additions as a single work package. Patch Gitea inside the deadline, sweep the hooks directory, rotate credentials that touched write-capable repositories, and use the same maintenance window to close the SSRF and command-injection surfaces that would otherwise let an attacker reach or pivot from your source-of-truth server.
Verifiable security.