# Gitea Container Registry Authorization Bypass (CVE-2026-27771) — Unauthenticated Pull of Private Container Images Across 31,000+ Self-Hosted Instances

> CVE-2026-27771 is a missing-authorization flaw in Gitea's package registry (also affecting the Forgejo fork) that allowed any unauthenticated remote user to pull container images and access package source metadata for repositories marked private or internal. Security firm Noscope identified ~31,750 likely-affected instances across 30+ countries spanning healthcare, aerospace, retail, ISPs, and SaaS, with two-thirds of exposure concentrated in China, the United States, and Germany. The vulnerable code path existed for roughly four years and was patched in Gitea 1.26.2 (released 2026-05-20); public disclosure followed on 2026-05-25.

- **Published:** 2026-05-27T00:00:00Z
- **Last reviewed:** 2026-05-27T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-0602
- **ID:** TL-2026-0602
- **Severity:** HIGH
- **Category:** VULNERABILITY
- **Status:** MONITORING
- **Detections:** 9 · **IOCs:** 16 (full data via the Threadlinqs MCP server — Purple tier)
- **CVEs:** CVE-2026-27771

## Description

Overview

CVE-2026-27771 is an improper-authorization (CWE-285 / CWE-862) vulnerability in the Gitea package registry subsystem that affects all Gitea releases prior to 1.26.2 and the upstream-derived Forgejo distribution. The flaw allows an unauthenticated remote attacker — with no Gitea account, API token, or registry credentials — to retrieve container images, Composer package source URLs, and other package metadata from repositories that operators explicitly marked private or internal. Because Gitea is a widely deployed self-hosted DevOps platform (a Gogs-derived alternative to GitHub Enterprise and GitLab Self-Managed), the issue exposes source code artifacts, build outputs, configuration baked into images, and any secrets accidentally embedded in private container layers (cloud credentials, API keys, internal CA material, signing keys, registry tokens).

Technical Root Cause

The root cause sits in the shared package-permission code path that Gitea's container registry, Composer registry, and other package-type handlers all build on top of. The patch commit (PR #37610, ''fix(packages): Add label for private and internal package and fix composor package source permission check'', credited to NoScope and implemented by Gitea maintainer @lunny) modifies routers/api/packages/composer/api.go so that createPackageMetadataResponse now invokes GetDoerRepoPermission against the package''s owning repository before populating Composer source URL fields in the response payload. Code reviewers on the PR explicitly flagged that the helper must use HasAnyUnitAccessOrPublicAccess rather than HasAnyUnitAccess to correctly handle repositories with public-unit-only configurations (where the repo is private but selected units are exposed). The PR also adds visibility badges across package list, detail, settings, and cleanup-preview templates so that operators can no longer be deceived by a UI that displays packages without indicating their private/internal scope.

The practical effect on the OCI surface is that an unauthenticated GET against /v2/{owner}/{image}/manifests/{tag} or /v2/{owner}/{image}/blobs/sha256:{digest} returned 200 for images attached to private repositories rather than the expected 401 Unauthorized or 404 Not Found. Noscope explicitly withheld exact endpoint paths and exploitation payloads from their public writeup; the technical attribution above is derived from the only commit linked to CVE-2026-27771 in the Gitea 1.26.2 changelog. Although Noscope frames the impact in container-registry terms, the fix landing in the Composer/packages permission code indicates that the missing access check is in shared package metadata logic that the container registry inherits — meaning a single authorization fix closes both surfaces.

Exploit Chain

There is no privilege escalation or persistence sequence required: the entire chain collapses into a single unauthenticated HTTP GET. (1) Reconnaissance — Internet-wide scanning via Shodan, Censys, or simple HTTP probes against Gitea''s default port (3000) or HTTPS variants on 80/443 enumerates candidate instances; the Gitea UI banner and /api/v1/version endpoint readily fingerprint Gitea and Forgejo. (2) Target enumeration — The attacker queries /api/v1/repos/search and /api/v1/users/search to identify owners and repositories, then probes /api/packages/{owner}/{type}/{name} to enumerate package names attached to private repositories. (3) Manifest pull — An OCI client (docker pull, skopeo copy, oras pull, or raw curl against /v2/) requests the manifest for the target image; under the vulnerable code path the registry returns the manifest without an authorization check. (4) Blob retrieval — Each layer digest from the manifest is fetched via /v2/{owner}/{image}/blobs/sha256:{digest}; the attacker can reconstruct the entire image, including filesystem contents and environment-variable-baked secrets. (5) Secondary impact — Extracted images frequently contain build-time credentials, .env files, cloud SDK profiles, and private signing material, providing a pivot into the victim''s cloud, CI/CD, and code-signing infrastructure.

PoC and Exploitation Status

No public proof-of-concept code has been released. Noscope explicitly chose not to publish exploitation details or the exact endpoint paths and confirms they did not retrieve third-party private image content during their research. However, exploitation complexity is trivially low (no auth, no account, single unauthenticated GET against well-known OCI distribution endpoints), and the fix commit is public on GitHub — defenders should assume opportunistic scanning began on 2026-05-25 and treat the threat as POC_PUBLIC-equivalent.

Exposure Scale (Noscope research)

Noscope enumerated 34,144 internet-reachable Gitea hosts via Shodan and validated the issue against a 100-host sample, finding ~93 percent returned responses consistent with the bypass — yielding an estimated 31,750 likely-affected instances. Two-thirds of exposed infrastructure sits in China, the United States, and Germany, with France and the United Kingdom also heavily represented and 30+ countries in total. Fifty-two percent of affected hosts run on major cloud or VPS providers, and 68 percent listen on Gitea''s default port. A targeted 10-host inspection identified affected organizations across healthcare providers, aerospace and industrial manufacturing, retail infrastructure, ISPs, software development shops, social media platforms, enterprise CMS deployments, and SaaS/EdTech vendors.

Detection Surface

Defenders should watch for unauthenticated HTTP GETs returning HTTP 200 against /v2/{owner}/{image}/manifests/* and /v2/{owner}/{image}/blobs/sha256:* for repositories that were configured private, bursts of /api/packages/{owner}/composer/p2/*.json requests from unauthenticated sources after 2026-05-25, and generic OCI client user-agents (docker/, containerd/, skopeo/, oras/, go-containerregistry/) hitting private package paths without Authorization headers. Reverse-proxy access logs are typically the highest-fidelity source.

Remediation

Upgrade Gitea to 1.26.2 or later immediately. Forgejo operators should track upstream patch backport at codeberg.org/forgejo/security-announcements. If patching cannot be deployed in the immediate window, set [service].REQUIRE_SIGNIN_VIEW=true in app.ini — this forces authentication for all content access and mitigates the CVE at the cost of breaking intentionally-public repositories. As defense-in-depth, restrict /v2/ and /api/packages/ endpoints via reverse-proxy ACL or WAF rules until the upgrade lands, audit unauthenticated GETs against those paths in retained access logs, and rotate any secrets that may have been baked into container images intended to be private (cloud credentials, signing keys, registry tokens, internal API keys).

Forks and Derivatives

Forgejo is confirmed affected by Noscope through independent testing (it shares Gitea''s package registry implementation). Other Gitea forks should be treated as affected until each vendor publishes an explicit advisory. Self-built or vendored Gitea instances must apply the Gitea 1.26.2 patches (commit set referenced by PR #37610) before being considered remediated.

## MITRE ATT&CK

- T1595 Active Scanning
- T1595.002 Active Scanning: Vulnerability Scanning
- T1592 Gather Victim Host Information
- T1596 Search Open Technical Databases
- T1596.005 Search Open Technical Databases: Scan Databases
- T1190 Exploit Public-Facing Application
- T1078 Valid Accounts
- T1552 Unsecured Credentials
- T1552.001 Unsecured Credentials: Credentials In Files
- T1552.007 Unsecured Credentials: Container API
- T1552.005 Unsecured Credentials: Cloud Instance Metadata API
- T1526 Cloud Service Discovery
- T1613 Container and Resource Discovery
- T1213 Data from Information Repositories
- T1213.003 Data from Information Repositories: Code Repositories
- T1567 Exfiltration Over Web Service
- T1048 Exfiltration Over Alternative Protocol

## Sources

- [Gitea Vulnerability Exposes Private Container Images without Authentication (The Hacker News)](https://thehackernews.com/2026/05/gitea-vulnerability-exposes-private.html)
- [Gitea Instances Exposing Private Container Images (Noscope research blog)](https://www.noscope.com/blog/gitea-instances-exposing-private-container)
- [Gitea 1.26.2 release notes — CVE-2026-27771 listed](https://blog.gitea.com/release-of-1.26.2/)
- [Gitea PR #37610 — fix(packages): Composer source permission check + private/internal labels](https://github.com/go-gitea/gitea/pull/37610)
- [Gitea Security Advisories index](https://github.com/go-gitea/gitea/security/advisories)
- [NVD record for CVE-2026-27771 (RESERVED at disclosure time)](https://nvd.nist.gov/vuln/detail/CVE-2026-27771)
- [Gitea Container Registry documentation](https://docs.gitea.com/usage/packages/container)
- [Forgejo Security Announcements](https://codeberg.org/forgejo/security-announcements/issues)
- [Gitea Security page](https://about.gitea.com/security)

## Full data

Detection queries (Splunk SPL / Microsoft KQL / Sigma) and IOC values require the Threadlinqs MCP server (Purple tier): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-0602
