NOW Briefing
[service].REQUIRE_SIGNIN_VIEW=true로 비인증 조회를 차단해야 합니다.
Gitea 비공개 컨테이너 이미지 노출 취약점 (CVE-2026-27771)
■ 개요
Gitea는 자체 호스팅형 Git 서비스로, 코드 저장소뿐 아니라 컨테이너 이미지와 패키지를 보관하는 레지스트리 기능을 제공합니다. 이번 결함은 이 레지스트리의 접근 제어 누락에서 비롯됐습니다. 저장소를 "비공개"로 표시하더라도 컨테이너 이미지 pull 요청에는 권한 검증이 적용되지 않았기 때문입니다.
이 구조 때문에 핵심 위험은 사전 인증(pre-auth) 노출입니다. 공격자는 계정이나 토큰 없이도 비공개로 분류된 이미지를 내려받을 수 있었습니다. 컨테이너 이미지에는 애플리케이션 코드와 의존성은 물론, 빌드 과정에서 포함된 DB 자격증명·API 키·프로덕션 인프라 정보가 담기는 경우가 많아 단순 코드 유출을 넘어 2차 피해로 이어질 수 있습니다.
NoScope는 약 4년간 결함이 발견되지 않았다고 분석했고, Shodan 기준 영향 가능 인스턴스는 약 3만 1,750개로 집계했습니다. 자체 호스팅 Gitea는 보안 패치 적용이 운영자 책임이므로, 노출 여부를 즉시 점검하고 패치를 적용해야 합니다. 아래 요약은 영향 범위와 우선 대응 기준을 정리한 것입니다.
■ 요약
| 항목 | 내용 |
|---|---|
| CVE ID | CVE-2026-27771(Gitea 비공개 컨테이너 이미지 노출) |
| CVSS 점수 | 공개 자료 기준 공식 점수 확인 불가, 비인증 접근 제어 우회로 위험도 높음 |
| 취약점 유형 | 접근 제어 결함(Broken Access Control), 인증 우회 |
| 영향/위험 |
- 비인증 공격자의 비공개 컨테이너 이미지 pull 가능 - 코드·의존성·자격증명·API 키 유출 가능 - 유출된 자격증명을 이용한 내부 확산·2차 침해 가능 |
| 취약 버전 | v1.26.2 미만 Gitea, 동일 레지스트리 구현을 공유하는 포크(fork) |
| 패치 버전 | Gitea v1.26.2 이상 |
📘 INFO
NoScope 분석에 따르면 영향 가능 인스턴스의 52%가 주요 클라우드 플랫폼에서 운영 중이며, 68%가 기본 포트 구성을 사용했습니다.
결함은 30여 개국에서 확인됐고 중국·미국·독일이 약 3분의 2를 차지한 것으로 보고됐습니다.
■ 기술 분석
근본 원인은 패키지 레지스트리 응답 경로의 저장소 권한 검증 누락입니다. 컨테이너 이미지를 비공개로 지정해도 레지스트리가 이를 공개 저장소처럼 처리해, 비인증 요청에 메타데이터와 이미지 레이어를 반환할 수 있었습니다. NoScope는 익스플로잇 코드를 공개하지 않고 메인테이너에만 전달했습니다.
보안 패치는 패키지 메타데이터를 반환하기 전에 호출자의 저장소 권한을 확인하도록 변경했습니다. 아래는 Composer 패키지 엔드포인트(routers/api/packages/composer/api.go)에 권한 검증이 추가된 diff로, 레지스트리 전반에 적용된 권한 확인 패턴입니다. 권한이 없으면 저장소 Source 정보를 채우지 않습니다.
// routers/api/packages/composer/api.go
/* [패치 전] */
- pkg.Source = Source{
- URL: pd.Repository.HTMLURL(),
- Type: "git",
- Reference: pd.Version.Version,
/* [패치 후] */
+ permission, err := access_model.GetDoerRepoPermission(ctx, pd.Repository, ctx.Doer)
+ if err != nil {
+ log.Error("GetDoerRepoPermission[%d]: %v", pd.Repository.ID, err)
+ } else if permission.HasAnyUnitAccessOrPublicAccess() {
+ pkg.Source = Source{
+ URL: pd.Repository.HTMLURL(),
+ Type: "git",
+ Reference: pd.Version.Version,
+ }
핵심은 GetDoerRepoPermission으로 호출자 권한을 조회한 뒤 HasAnyUnitAccessOrPublicAccess()를 통과한 경우에만 민감 정보를 반환하도록 게이트를 추가했다는 점입니다. 반면 패치 전에는 이 검증 없이 정보가 노출됐습니다. v1.26.2 릴리스 노트에도 패키지 비공개·내부 표시 추가와 권한 검증 패치 항목이 포함돼 있습니다.
⚠️ WARN
비공개 표시만 믿고 운영해 온 인스턴스라면 결함 잠복 기간(약 4년) 동안 이미 임의 pull이 발생했을 수 있습니다.
패치 적용 여부와 무관하게, 노출됐던 이미지에 포함된 자격증명·토큰은 유출된 것으로 간주하고 교체해야 합니다.
■ 탐지 및 점검
앞선 분석에서 확인한 결함이 자사 환경에 영향을 미치는지 판단하려면 다음 항목을 순서대로 점검해야 합니다.
✅ CHECK
외부에 노출된 Gitea 레지스트리는 비인증 pull 가능 여부와 접근 로그를 함께 점검해야 합니다.
• 운영 중인 Gitea 버전을 확인하고 v1.26.2 미만이면 영향 대상으로 분류합니다. 관리 화면 또는 바이너리 버전 정보를 점검합니다.
• 인스턴스가 인터넷에 직접 노출됐는지, 기본 포트(3000) 또는 리버스 프록시로 외부에서 접근 가능한지 확인합니다.
• 비공개로 지정한 컨테이너·패키지 저장소에 인증 헤더 없는 요청이 성공하는지 통제된 환경에서 점검합니다.
• 웹 서버·프록시 접근 로그에서 비인증(토큰·세션 없는) 상태로 레지스트리 경로에 접근한 요청과 비정상적인 이미지 manifest(이미지 구성 정보)·blob(이미지 데이터) 다운로드 패턴을 조사합니다.
• 노출 가능성이 있던 비공개 이미지 목록을 식별하고, 해당 이미지에 포함된 비밀 정보 범위를 파악합니다.
■ 대응 방안
점검 결과 영향이 확인됐다면, 노출 경로 차단과 비밀 정보 교체를 함께 진행해야 합니다. 특히 비인증 pull이 가능했거나 로그상 의심 접근이 확인된 경우라면 더욱 신중하게 대응해야 합니다.
💡 TIP
패치는 노출 경로를 차단할 뿐, 이미 유출됐을 수 있는 비밀 정보를 무효화하지는 않습니다. 패치와 자격증명 교체를 함께 진행해야 합니다.
• Gitea를 v1.26.2 이상으로 즉시 업데이트합니다. 포크(Forgejo 등) 사용 시 동일 레지스트리 구현의 영향 여부와 패치 버전을 별도로 확인합니다.
• 즉시 패치가 어려운 경우 임시 대응책으로 [service].REQUIRE_SIGNIN_VIEW=true를 설정해 비인증 조회를 차단합니다.
• 노출됐을 수 있는 이미지에 포함된 DB 자격증명·API 키·토큰은 유출된 것으로 간주하고 즉시 교체합니다.
• 외부 노출이 불필요한 인스턴스는 방화벽·접근 제어로 레지스트리 접근 범위를 내부망·신뢰 IP로 제한합니다.
[참고 자료]
NoScope, Gitea instances exposing private container images
Gitea PR #37610, package visibility & composer source permission check



