Gitea CVE-2026-27771: Anyone Could Pull Your Private Container Images for 4 Years

A missing authorization check in Gitea's container registry let anyone on the internet pull private images from ~31,750 instances for roughly four years. Forgejo is affected too. Patch to 1.26.2 — and treat every secret baked into a reachable image as burned.

Share
Line-art server rack holding stacked container boxes, one container's padlock hanging open and carrying a single flat red dot at its shackle.

The point of running your own Gitea server is to keep your code and container images off somebody else's cloud. CVE-2026-27771 quietly inverted that premise. A missing authorization check in Gitea's built-in container registry meant that for roughly four years, any private image on an internet-reachable, unpatched instance could be pulled by anyone on the internet — no account, no token, no password. Researchers who mapped the exposure found about 31,750 reachable instances across 30-plus countries. The deployment never failed to be secret. It failed to be private.

Gitea assigned the flaw CVE-2026-27771, rated it CVSS 8.2 (High), and fixed it in Gitea 1.26.2. The vulnerability class is CWE-862, Missing Authorization: on the registry pull path, the check that was supposed to enforce a repository's “private” designation simply did not run. It was discovered in April 2026 by NoScope's autonomous penetration-testing agent, reported to Gitea, and patched — but the exposure window stretches back to when the container registry feature first shipped in Gitea 1.17.0, around 2022.

  HOW "PRIVATE" BECAME PUBLIC
CVE-2026-27771: a private image was only ever as private as one access check — and that check was missing.
STRUCTURAL PREMISE
A self-hosted Gitea instance holds container images marked "private" — the whole reason the org runs its own registry instead of a public one.
THE MISSING CHECK
On the registry pull path, the authorization check (CWE-862) never enforced the "private" flag — a gap that shipped with the feature ~4 years ago.
UNAUTHENTICATED PULL
Any anonymous Docker/OCI request reaches the endpoint — no account, token, or password — and the registry serves the layers and manifests.
SOURCE + SECRETS EXPOSED
The attacker walks out with proprietary code and whatever was baked into build layers: cloud keys, API tokens, signing material. ~31,750 instances were reachable.
Source: NoScope research; Gitea security advisory (fix in 1.26.2); Orca Security.

What the flaw actually does

Gitea exposes an OCI-style container registry alongside its Git repositories, so teams can host private images next to the source that builds them. On affected versions — Gitea 1.17.0 through 1.26.1, and its fork Forgejo through 1.26.1 — the registry served image layers and manifests to anonymous Docker/OCI pull requests even when the repository was marked private. The “private” flag was set in the UI, but nothing on the pull endpoint enforced it. Per Orca Security and Horizon3, the same missing-authorization pattern also touched the Composer package-registry metadata API, so this is not strictly a container-only problem.

Two facts sharpen the risk. First, a public proof-of-concept now exists and researchers report active internet scanning for exposed instances — so the “no PoC, no confirmed exploitation” framing that accompanied early disclosure no longer holds. Second, the bug is trivially exploitable: reaching the endpoint over the network is the entire attack. There is no session to hijack, no credential to phish, nothing an access log would flag as suspicious beyond an anonymous pull that succeeded.

Why a leaked image is worse than leaked source

Losing proprietary code is bad enough. What makes CVE-2026-27771 a credential-exposure problem rather than a confidentiality one is what tends to live inside container images. Build pipelines routinely bake secrets into layers — cloud credentials in environment variables, API tokens written into config files, database connection strings, signing keys copied into intermediate stages, sometimes private SSH keys pulled in to clone dependencies. Container-secret audits find this constantly. An attacker who can pull every private image from an exposed registry is not just exfiltrating application code; they are collecting the build-time secret-hygiene failures of every developer who ever pushed an image. That is why patching alone does not close this incident — the secrets that were reachable have to be treated as burned.

My Read

Self-hosting a developer platform is almost always a trust decision dressed up as a technical one. The argument — owning the box, controlling the network, keeping artifacts off a vendor's SaaS — is real, but it quietly transfers the entire burden of every access-control decision from the vendor to you. CVE-2026-27771 is what that transfer looks like when it goes wrong: a single missing check on a high-value endpoint, unnoticed for four years, on the exact deployment an organization chose because it did not trust the SaaS alternative. The lesson is not that self-hosting is a mistake. It is that self-hosting is a higher-effort security posture than its advocates admit, and “private” is a promise your own code has to keep every single request.

It also fits a pattern The CyberSignal has tracked all year: the developer toolchain is now a tier-1 attack surface, and the self-hosted half is no longer the safe haven operators treated it as. This lands weeks after GitHub confirmed the TeamPCP theft of 3,800 internal repositories via a poisoned VS Code extension and the Megalodon campaign backdoored 5,561 repositories through CI/CD workflow files. The Verizon DBIR 2026 found vulnerability exploitation just overtook credential theft as the top initial-access method — and unauthenticated auth-bypasses on internal dev tools are exactly the finding that pattern says gets weaponized fast.

What to do now

If you run self-hosted Gitea or Forgejo, treat this as active:

  • Upgrade to Gitea 1.26.2 (or the patched Forgejo release) today. This is the only real fix. Any internet-reachable instance below the patch should be assumed exploitable right now, given the public PoC and ongoing scanning.
  • Bridge the gap if you can't patch instantly. Set [service].REQUIRE_SIGNIN_VIEW=true to block anonymous access, put an authentication-required reverse proxy in front of the registry endpoints, or take the registry offline until the upgrade lands. Do not lean on network segmentation for a service that has been internet-facing.
  • Rotate every secret that could have been in a reachable image. Cloud credentials, API tokens, database passwords, signing keys, certificate and SSH material — assume anything baked into a build layer during the exposure window is compromised, and re-baseline image scanning to catch what should never have been there.
  • Audit the exposure window, not just today. Hunt Gitea/Forgejo registry access logs for successful anonymous pulls of private images going back years, and treat any pull from an unfamiliar IP as an investigation lead, not a closed event.
  • Check your external footprint and the rest of your toolchain. Confirm the registry is no longer serving private images to unauthenticated requests, and audit every other self-hosted platform with a bolted-on registry for the same missing-authorization class.

Open questions

Several things remain genuinely unconfirmed, and this account does not pretend otherwise. There is no public tally of how many of the ~31,750 exposed instances were actually pulled from before patching, and no named victim organizations. Whether attackers enumerated images and tags they did not already know about — versus only pulling known paths — has not been fully characterized. CISA has not, as of writing, added CVE-2026-27771 to its Known Exploited Vulnerabilities catalog, and no specific threat actor has been tied to exploitation. Forgejo operators should follow their project's own advisory for the exact patched version rather than infer it from Gitea's.

Primary Documents