---
schema: 1
kind: vulnerability
title: "CVE-2026-60004: Gitea's diffpatch endpoint turns an attacker-supplied patch into a live Git hook, giving command execution as the service account; KEV-listed after miner deployment"
headline: "Applying the same patch twice writes an executable into $GIT_DIR of a bare clone, and Git then runs it as the Gitea user"
summary: >
  CISA added CVE-2026-60004 (CVSS 9.8) to the Known Exploited Vulnerabilities catalog on
  2026-08-25. Gitea's diffpatch endpoint applies attacker-controlled patches inside a shared bare
  temporary clone; submitting the same patch twice forces a three-way merge fallback that checks
  the indexed path out even under --cached, and because a bare clone's repository root is $GIT_DIR,
  an executable entry named as a hook path becomes a live hook that Git invokes while writing the
  index. Exploitation needs only ordinary repository write access, which default open registration
  hands to any visitor. Fixed in Gitea 1.27.1. A compromised self-hosted instance was
  reached end to end by an automated scanner that registered, created a repository and dropped a
  shell loader and a miner.
discovered_at: "2026-08-30T13:12:06Z"
updated_at: null
event_date: "2026-08-25"
run_id: 2026-08-30T1312Z-audit
priority: high
immediate_action: null
tags: [vulnerabilities, actively-exploited, cisa-kev, rce, pre-auth, default-config, patch-available, poc-public, cryptocrime]
regions: [global, europe]
sectors: [public-sector]
entities: ["product:gitea"]
techniques: [T1190, T1105, T1496, T1552.001]
affected_products: ["Gitea"]
cves:
  - id: CVE-2026-60004
    cvss: "9.8"
    epss: null
    type: rce
    vector: zero-click
    auth: pre-auth
    status:
      - exploited
      - cisa-kev
      - poc-public
      - patch-available
    affected: >
      Gitea before 1.27.1; effectively unauthenticated on any instance leaving the default open
      user registration enabled
    fixed: "Gitea 1.27.1"
sources:
  - url: "https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m"
    publisher: "Gitea maintainers (GitHub Security Advisory)"
    date: "2026-07-28"
    role: primary
  - url: "https://www.helpnetsecurity.com/2026/08/26/gitea-cve-2026-60004-exploited-in-the-wild/"
    publisher: "Help Net Security"
    date: "2026-08-26"
    role: corroborating
closed_sources: []
evidence:
  - quote: "An attacker with ordinary write access to a repository can execute arbitrary shell commands as the Gitea OS user. With default open registration, an unauthenticated visitor can obtain the required write access by registering an account and creating a repository."
    publisher: "Gitea maintainers (GitHub Security Advisory)"
  - quote: "Submitting the same patch twice creates an add/add collision. Git's three-way fallback checks the indexed path out even though the operation is performed with `--cached`."
    publisher: "Gitea maintainers (GitHub Security Advisory)"
  - quote: "Because the server ran an outdated version of Gitea, with open user registration and no email confirmation or CAPTCHA, an automated scanner was able to register an account, create its own repository, and trigger the exploit chain."
    publisher: "Help Net Security"
verification: multi-source
sourcing_note: >
  The mechanism, the affected versions and the open-registration precondition come from the Gitea
  maintainers' own advisory, which is first-party for their own product and ships a working
  proof-of-concept. The exploitation account is Help Net Security's reporting of an incident
  write-up published on Habr by the operator of the compromised instance; that operator is
  self-identified and the write-up itself is not among the sources read, so the attack narrative is
  carried at one remove and attributed to Help Net Security rather than treated as forensic
  confirmation. The same reporting states that no persistence via cron, systemd or new SSH keys was
  found, which is why nothing here is mapped as persistence. CISA's KEV entry points to no attack
  detail of its own. No source read gives a release date for 1.27.1, so the version is stated
  without one.
confidence: high
references: []
deep_dive: false
deep_dive_category: null
org_triage: null
classification:
  reliability: A
  credibility: 1
watchlist_hit: false
actions:
  - "Upgrade every self-hosted Gitea instance to 1.27.1 or later, and on any instance that was internet-reachable on an older build with open registration, rotate what the service account could read: the Gitea configuration file, database credentials, and any OAuth or integration credentials in its process environment. The patch does not undo a prior compromise, and credential exposure is the durable half of this one."
  - "Audit user accounts created since the instance was last patched and delete the repositories they created. The observed access path is self-registration followed immediately by repository creation, so a recently self-registered account owning one throwaway repository is the artefact to look for."
updates: []
migrated_from: null
---

CISA added CVE-2026-60004 to the Known Exploited Vulnerabilities catalog on 2026-08-25. The flaw is in `services/repository/files/patch.go`, the code behind Gitea's diffpatch endpoint, which applies an attacker-controlled patch inside a shared bare temporary clone. The maintainers describe the chain precisely: "submitting the same patch twice creates an add/add collision. Git's three-way fallback checks the indexed path out even though the operation is performed with `--cached`" ([Gitea maintainers, 2026-07-28](https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m)). In a bare clone the repository root *is* `$GIT_DIR`, so a checked-out executable entry whose path matches a Git hook name is not a file sitting next to the hooks directory, it is a hook. Git then invokes it while writing the index, and it runs as the Gitea OS account.

The precondition is the part worth reading twice. The advisory states it plainly: "an attacker with ordinary write access to a repository can execute arbitrary shell commands as the Gitea OS user. With default open registration, an unauthenticated visitor can obtain the required write access by registering an account and creating a repository" (same advisory). Ordinary write access is not a privileged role, it is what every user of a Git forge has by definition, and Gitea's shipped default hands it to anyone who can reach the login page. So on a default-configured instance this is a pre-authentication flaw in every sense that matters operationally, separated from an anonymous visitor only by a registration form. Fixed in Gitea 1.27.1. The advisory carries a working proof-of-concept, which arrived with it.

**Exploitation is opportunistic and automated.** Help Net Security reports the incident write-up of an operator whose self-hosted instance was compromised: "because the server ran an outdated version of Gitea, with open user registration and no email confirmation or CAPTCHA, an automated scanner was able to register an account, create its own repository, and trigger the exploit chain" ([Help Net Security, 2026-08-26](https://www.helpnetsecurity.com/2026/08/26/gitea-cve-2026-60004-exploited-in-the-wild/)). The chain wrote a proof of execution into a Git branch, then pulled a shell loader followed by a miner; the operator was alerted not by security tooling but by the hosting provider flagging sustained CPU. That is a mass-scanning profile against a default configuration, not targeted intrusion, and it means exposure is a function of being reachable rather than being interesting.

The blast radius is broader than the payload suggests. Depending on container isolation and the privileges of the Gitea OS user, exploitation can expose the main configuration file, application and process-environment secrets, database credentials and contents, and OAuth and integration credentials (same reporting). A miner is the noisy outcome; the quiet one is a set of credentials into whatever the forge is wired to, which for a public-sector development estate typically means CI runners, artefact registries and identity providers.

**Where the activity surfaces.** The exploitation itself looks like ordinary API traffic, so the durable signal is what the service account does immediately afterwards. Watch for the Gitea service account spawning a shell or an interpreter within seconds of a patch or diff API call, on a host whose normal process tree is a Go binary plus `git`. On the repository side, the artefact is a Git hook whose content arrived through patch application rather than through an administrator action, so an executable object at a hook path in a repository nobody manages is the thing to hunt for. Registration and repository-creation events are the leading indicator: on an instance with real users, a self-registered account creating a single repository and immediately exercising the diff endpoints is not a normal usage pattern.

**Triage:** the benign lookalike is a legitimate developer using diffpatch to apply a patch, which is what the endpoint is for and which will be the overwhelming majority of hits on that route. Two things separate exploitation from it. First, the same patch applied twice in quick succession, which is the collision the attack requires and which a human working normally has no reason to produce. Second, and more reliably, what happens next: a legitimate patch application ends with a commit, while this one ends with the service account executing something. Alert on the process behaviour, use the endpoint traffic to explain it.

**Defender takeaway:** patch to 1.27.1, then close the registration path, because the patch fixes this flaw while open self-registration keeps handing anonymous visitors the exact privilege level that the next repository-scoped bug will need. For any instance that ran an older build while internet-reachable, treat the service account's secrets as exposed and rotate them; a miner that was killed by a container restart, which is what happened in the reported case, says nothing about what was read before it started.
