New Gitea RCE Lets Repository Writers Plant a Git Hook to Run Shell Commands

New Gitea RCE Lets Repository Writers Plant a Git Hook to Run Shell Commands

Swati KhandelwalJul 29, 2026Vulnerability / DevOps

Gitea, the self-hosted Git platform, has patched a critical remote code execution vulnerability. A user with ordinary repository write access can turn attacker-controlled patch content into a live Git hook and run shell commands as the Gitea service account.

Tracked as CVE-2026-60004 (CVSS score: 9.8), the flaw affects Gitea versions 1.17 and later before 1.27.1 and is fixed in 1.27.1. The vulnerable API call requires authentication and repository write permission. But Gitea enables registration by default, so an outside visitor can create a normal account and repository on an unchanged installation, then exploit the bug without pre-existing credentials.

Upgrading to 1.27.1 is the fix. Gitea said on July 27 that Gitea Cloud instances would be upgraded automatically. Gitea’s July 28 advisory does not say the flaw has been exploited in the wild, but it includes public proof-of-concept (PoC) code.

Disabling open registration can remove the public account-creation path while the update is deployed, but it does not fix the flaw or protect against existing users with repository write access.

The flaw was reported by security researcher Shai Rod, who goes by NightRang3r. Gitea credits NightRang3r as the reporter in its advisory.

Gitea’s affected route invokes reqToken(), which rejects requests without a signed-in user. The no-prior-credentials path comes from the project’s default configuration, which leaves registration open, requires neither email nor manual approval, does not mark new users as restricted, and imposes no default repository-creation limit.

The bug sits in the POST /api/v1/repos/{owner}/{repo}/diffpatch endpoint. According to Gitea’s security advisory, the endpoint applies a supplied patch inside a shared bare temporary clone. Vulnerable builds invoke git apply with --index, --recount, --cached, and --binary, adding the -3 three-way fallback option when the server runs Git 2.32 or later.

An attacker submits the same patch twice to create an add/add collision. The three-way fallback then checks the indexed path out even though the operation uses --cached. Because the temporary clone is bare, its root is $GIT_DIR. An executable file placed at hooks/post-index-change therefore lands in Git’s hook directory and becomes active. Git runs it while updating the index.

The PoC signs in with a normal account, creates an initialized private repository, sends the malicious patch twice, and retrieves the command output. It needs no outbound callback. The hook stores the output in Git objects, creates a branch containing the result, and lets the attacker fetch it over authenticated smart HTTP.

As of July 29, 2026, none of the cited primary sources reports whether the flaw was exploited before or after version 1.27.1 became available.

Successful exploitation gives the attacker the privileges of the Gitea operating-system account. Depending on how the instance is isolated, Gitea said that could expose application and environment secrets, mounted repositories, database credentials and contents, OAuth credentials, and reachable internal services.

Exploitation still requires repository write access, Git 2.32 or later, an enabled diffpatch route, and a writable, executable temporary filesystem. Default registration lets an outsider obtain the required write access on an unchanged installation.

The fix is easy to miss in the changelog. Gitea changed the temporary clone from bare to non-bare. The code comment explicitly warns that Git commands using --index may operate on the working tree. The change was merged and backported on July 26, 2026.

Version 1.27.1 shipped on July 27, and the security advisory followed on July 28. The release notes listed the change under MISC as “refactor: git patch apply,” not under SECURITY.

Rod had previewed the RCE alongside a separate file-inclusion issue, with a PoC retrieving /etc/passwd from a Gitea 1.27.0 host. That issue appears to correspond to a separate change included in 1.27.1 that altered Gitea’s Org-mode renderer so #+INCLUDE paths are returned as plain text instead of being read from the server’s filesystem. Gitea has not published a separate advisory or CVE for the file-inclusion issue.

Source link

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *