A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.
A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.
The Forgejo RCE template repository flaw let a template write its own .git folder. Two other fixes in release 16.0.4 fail in exactly the same way.

Forgejo 16.0.4 fixes a critical Forgejo RCE template repository flaw: generating a new repository from a template could let a malicious template read arbitrary data from the host and execute arbitrary processes on it. If you run a self-hosted forge, patch it. Then read the rest of the release notes, because two other fixes in the same version fail in precisely the same way, and that pattern is the part worth keeping.
The release notes describe the mechanism in four steps. When generating a new repository from a template, Forgejo clones the template repository, removes the .git folder, performs variable template expansion on the files listed in .forgejo/template, and then initialises a new git repository.
The order is the bug. Removal of .git happens before expansion, and expansion writes files. So variable expansion could be misused to create a new .git folder — one that git would then adopt and incorporate when it initialised the new repository. A directory that arrives carrying its own git metadata is not an empty directory, and git init is happy to inherit what it finds. From there the release notes are blunt about the consequence: a malicious template repository could read arbitrary data from the Forgejo host and execute arbitrary processes on it, as a remote code execution attack.
The fix is a single reordering. After variable expansion completes, any existing .git folder is removed from the directory before the repository is initialised. Clean up last, not first.
The same release fixes an authorisation control that did not apply everywhere it should. Forgejo lets repository maintainers edit branches they do not own when an open pull request has the "allow maintainer edit" option set. That control did not account for API-specific restrictions such as repo-scoped access tokens, so a token with restricted permission could make modifications outside that restriction.
And it fixes a disclosure: users with only read permission, including unauthenticated callers on public repositories, could retrieve the metadata and full contents of attachments belonging to draft releases. The GetReleaseAttachment API endpoint and the web attachment download route did not check whether the release was a draft, while GetRelease and ListReleaseAttachments already did.
That third one has a history worth following, because it is the same bug being found for the third time. Gitea fixed the API surface in February 2026 as CVE-2026-27660. The web-level UUID attachment routes were missed, and were reported separately as CVE-2026-58432, where the advisory notes that anyone who obtains an attachment UUID can download its contents despite the draft release being correctly hidden from listings — and that the UUID is embedded in the browser_download_url the API hands out. Forgejo then had to fix its own copy.
Three fixes, one failure mode. A rule is enforced on one code path and not its twin. Expansion is cleaned up before the step that can dirty it. A permission check lives on the API route and not the web route. An override is written for session authentication and never reconsidered for tokens. None of these is an exotic vulnerability class; all of them survive review because the reviewer is looking at the path in front of them rather than the set of paths that reach the same resource.
The transferable lesson outlives the patch. Repository templating looks like a convenience feature and behaves like a code execution surface. Something arrives from outside your trust boundary, your server expands it, and the expansion writes to a filesystem your own tooling is about to interpret. That is the same structure as any injection bug, with a filesystem in place of a string parser.
It is also a structure we keep meeting in different costumes. A comment on a pull request becomes instructions to a workflow runner, which is how GitHub Actions prompt injection reaches your secrets. A file in a working directory becomes instructions to an agent, which is why sandbox design starts with the allowlist. The forge case is older and simpler than either, and it is still shipping in 2026.
Worth asking about your own systems: what content does a user supply that your server writes to disk and then acts on? Uploaded archives that get extracted. Configuration files read after a merge. Anything expanded from a template. Each of those is a place where the order of clean-up and expansion decides whether you have a feature or an exploit.
The last one is the recurring finding. Self-hosted developer infrastructure tends to be installed once, by whoever needed it, and then inherited. It holds every line of source you own and often the credentials to deploy it, and it is patched on a slower cycle than anything customer-facing because nothing breaks when you delay. A forge belongs on the same upgrade and exposure review as your production systems, which is how we treat it under infrastructure monitoring and in any DevOps engagement — not because forge bugs are common, but because the blast radius when one lands is the whole codebase.
When generating a repository from a template, Forgejo removed the .git folder before expanding template variables. Expansion could be misused to write a new .git folder that git adopted during initialisation, letting a malicious template read arbitrary data from the Forgejo host and execute arbitrary processes on it.
Forgejo 16.0.4 contains the fix. After variable expansion completes, any existing .git folder is removed from the directory before the git repository is initialised. There is no configuration mitigation short of disabling repository generation from templates.
Two further access-control issues. A repo-scoped API token could modify branches outside its permission through the allow-maintainer-edit control, and read-only or unauthenticated callers could download attachments belonging to draft releases that were otherwise hidden from them.
Gitea fixed draft release attachment disclosure on its API endpoints in February 2026 as CVE-2026-27660. The equivalent web attachment routes were missed and reported separately as CVE-2026-58432. Forgejo's release notes describe its own fix as the same class of issue.
Yes, if draft releases held sensitive artefacts or if repo-scoped tokens were in use. Patching stops future access but does not revoke an attachment URL that was already shared, and reconstructing what a restricted token did historically is far harder than rotating it.
Template generation takes content from outside your trust boundary, expands it on your server, and writes the result to a filesystem your own tooling then interprets. That structure makes it a code execution surface worth reviewing, in any forge, rather than a purely cosmetic convenience feature.
Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.
11th Floor, O-Hub, Chandaka Industrial Estate, Infocity, Bhubaneswar, Odisha 751024
Level 4, 11 York Street Sydney Startup Hub Sydney, NSW – 2000
30 N. Đinh Nghệ, Phước Mỹ Sơn Trà, Đà Nẵng / Da Nang City – 550000
Level 25, AIDP Business Tower, Dubai Marina, United Arab Emirates
50 Beauchamp Street, Wellington, WGN 5028, New Zealand