Forgejo Fixed a Critical RCE Today — Here's Who Actually Has a CRA Article 14 Duty Tomorrow
Forgejo — the community-governed, self-hostable fork of Gitea that a lot of EU-sovereignty-minded teams run specifically to keep their code off GitHub's US infrastructure — shipped version 16.0.4 today, 2026-09-10. It fixes a critical remote-code-execution vulnerability, and the HN thread about it hit the front page within hours (86 points, 34 comments at the time of writing, four hours old).
The timing is genuinely notable for two unrelated reasons that happen to collide this week. First, this is a real, exploitable RCE in a tool a meaningful chunk of our readers actually run. Second, CRA Article 14 — the 24-hour/72-hour/14-day vulnerability-reporting duty from the Cyber Resilience Act — becomes legally binding tomorrow, 2026-09-11. That coincidence has been getting flattened online into "self-hosting Forgejo now triggers CRA duties," which isn't quite right. Below is what the bug actually does, how to patch it today, and a precise answer — grounded in the CRA's own definitions, not vibes — on who this reporting duty actually reaches.
What the vulnerability is
Quoting Forgejo's own release notes verbatim, because paraphrasing security advisories is how details go missing:
"Critical: fix: prevent template expansion from interfering with git repo initialization. When generating a new repository from a template repository, Forgejo clones the template repository, removes the
.gitfolder, performs variable template expansion on files listed in.forgejo/template, and initializes a new git repository. During this process, variable template expansion could be misused in order to create a new.gitfolder, which git would adopt and incorporate during its initialization of a new git repository. A malicious template repository could be used to read arbitrary data from the Forgejo host, and to execute arbitrary processes on the Forgejo host, as a remote code execution attack."
In plain terms: Forgejo's "generate repository from template" feature runs a variable-substitution pass over files in a special .forgejo/template directory before handing the result to git init. That substitution step didn't stop an attacker-controlled template from recreating a .git folder mid-process — and git init will happily adopt whatever .git folder it finds instead of creating a clean one. Since a .git folder can contain hooks, config, and other executable machinery, an attacker who controls a template repository's content controls what runs on your Forgejo host the moment someone instantiates a project from it.
The same release notes bundle two smaller fixes in the same patch (PR #14301): an authorization-scope bug where restricted API tokens with "allow maintainer edit" could exceed their intended scope on pull-request branches, and a separate, already-CVE'd issue (CVE-2026-27660 / GHSA-q9pg-jj6x-j9p6) where unauthenticated users could fetch draft-release attachments the GetReleaseAttachment endpoint should have hidden. Neither of those needs its own reporting decision the way the RCE does, but patch for all three at once — you're pulling one release either way.
We verified this is patched identically in both currently-supported release trains: 16.0.4 and 15.0.8, both published the same day with byte-identical wording for the critical fix. If you're on an older, unsupported train, Forgejo's own release cadence gives you the answer: there's no patch coming for it, so upgrade to a supported train — the exact "unmaintained dependency" scenario we wrote about two days ago applies to your own Forgejo version just as much as to any library you depend on.
Who's actually exposed
The attack needs two things to line up: someone (or some automated process) instantiating a new repository from a template, and an attacker who controls that template's content. That's a realistic threat model in exactly the deployments where Forgejo's self-sovereignty pitch is strongest:
- Open-registration instances where any signed-up user can create a public template repository, and another user — including an admin doing routine project setup — later generates a repo from it.
- Multi-team internal instances where template repositories are shared across teams with different trust levels (a common pattern precisely because templates are supposed to standardize project scaffolding).
- Any instance with a compromised low-privilege account. The attacker doesn't need admin rights to plant a malicious template — they need the ability to create one repository and mark it as a template, which is a default, low-privilege action in most Forgejo configurations.
A single-user, no-external-signups internal mirror is lower risk in practice, but "lower risk" isn't "no risk" once the technical detail is public — patch it regardless of your registration policy.
Patch now, in order:
- Check your running version: Forgejo's admin panel (Site Administration → the version string in the footer) or
curl https://<your-instance>/api/v1/version. - If you're on any 16.0.x release, upgrade to 16.0.4. If you're on any 15.0.x release, upgrade to 15.0.8. If you're on an older train, upgrade to a supported one first, then to its latest patch.
- Until you can upgrade, restrict who can mark a repository as a template and who can generate repositories from templates, via org/instance permission settings — this doesn't close the hole, but it shrinks the pool of people who could plant or trigger the malicious template.
- Audit repositories created from a template in the affected window for anything unexpected in
.git/hooks,.git/config, or unexplained processes spawned by the Forgejo service user — there's no public indicator-of-compromise list from this disclosure, so this is a manual review, not a signature scan. - If you're running Forgejo as a non-root service account inside a container with a read-only filesystem where possible, verify that's actually configured — it won't stop the RCE, but it meaningfully caps what "execute arbitrary processes on the Forgejo host" can actually reach.
One honest caveat: we found no evidence, as of publication, that this is being actively exploited in the wild — this looks like a proactive fix rather than an incident response. That's the best possible timing to patch: before the technical detail circulating publicly turns into working exploit code, not after.
If you run Gitea rather than Forgejo (Forgejo is a fork of Gitea, and the two still share a lot of code), note that the vulnerable code path is Forgejo's own .forgejo/template expansion mechanism specifically — don't assume this patch or this exact bug applies to Gitea without checking Gitea's own advisories separately.
The CRA Article 14 coincidence, scoped correctly
Here's where a lot of the online commentary oversimplifies. CRA Article 14 doesn't create a general "report every vulnerability in every tool you self-host" duty. It binds manufacturers of products with digital elements — both terms are defined in Article 3:
- A product with digital elements is "a software or hardware product and its remote data processing solutions, including software or hardware components being placed on the market separately."
- A manufacturer is "a natural or legal person who develops or manufactures products with digital elements or has products with digital elements designed, developed or manufactured, and markets them under its name or trademark, whether for payment, monetisation or free of charge."
The key phrase is "markets them under its name or trademark." That's the test — not "operates it" or "self-hosts it."
Forgejo the project itself is community-governed with no single commercial entity marketing it under a trademark for a fee — the kind of situation Article 24 was written for: it treats "open-source software stewards" (organizations that facilitate development of products with digital elements for commercial purposes on a sustained basis, without themselves being the manufacturer) more leniently than full manufacturers, requiring a documented vulnerability-handling policy rather than the full Article 13/14 obligation set, and the CRA's own penalty framework explicitly goes easier on stewards and non-commercial contributors than on manufacturers. Nothing about today's disclosure suggests Forgejo's maintainers owe an Article 14 report to ENISA for their own project.
Where real Article 14 exposure actually attaches, for sota.io's audience specifically:
| Your situation | CRA Article 14 duty for this RCE? |
|---|---|
| You self-host Forgejo purely as internal tooling (your team's git server, not sold or distributed to anyone) | No — you're not a "manufacturer" of Forgejo; you're an operator/user of someone else's open-source software |
| You resell, white-label, or bundle a Forgejo-based product under your own name/trademark (a hosted-git offering, an on-prem "DevOps appliance," etc.) | Yes — Forgejo is now a component of a product you market under your name; a vulnerability in it is a vulnerability in your product, reportable if actively exploited |
| Your internal Forgejo instance is part of the build/release pipeline for a separate product you do market as a manufacturer | Not for Forgejo itself — but a compromise via this RCE that reaches your build infrastructure could constitute a "severe incident affecting the security" of the product you ship, which is a distinct Article 14 trigger tied to that product, not to Forgejo |
| You're an essential/important entity under NIS2 (a different regulation, Directive (EU) 2022/2555) running Forgejo as critical infrastructure | Possibly a NIS2 incident-reporting duty, separately from CRA — don't conflate the two regimes; NIS2's reporting clock and CRA Article 14's are not the same obligation |
The middle two rows are the ones worth sitting with. If your company's answer to "do we ship anything under our own name that includes or depends on this Forgejo instance" is yes, this patch cycle is a genuine, live test of whether your incident-detection-to-24-hour-early-warning pipeline actually works — not a hypothetical exercise, starting tomorrow. If the honest answer is "we just run it for ourselves," you can patch this with operational urgency but without a regulatory reporting clock attached to the Forgejo instance itself.
The practical takeaway either way
Whether or not Article 14 reaches your specific setup, the underlying lesson is the same one we keep coming back to in this series: choosing self-hosted, EU-jurisdiction tooling to escape CLOUD Act exposure and vendor lock-in doesn't make patch management optional — it makes you the patch manager. Forgejo did its part here: a critical bug, fixed and disclosed with a precise technical writeup, backported same-day across two release trains. The remaining work — checking your version, upgrading, and knowing which regulatory clocks actually apply to your specific deployment — is now entirely on the people running it. If you're building EU-sovereign deployment pipelines around tools like Forgejo, that patch-now discipline is the whole point of the sovereignty trade — see our walkthrough of self-hosted git plus EU-native deployment for how the two fit together, and our Article 14 submission runbook for what actually happens if you do end up filing a report.
EU-Native Hosting
Ready to move to EU-sovereign infrastructure?
sota.io is a German-hosted PaaS — no CLOUD Act exposure, no US jurisdiction, full GDPR compliance by design. Deploy your first app in minutes.