文章总结: 本文分析CVE-2026-85706GitLab未授权任意文件读取漏洞,根因是Workhorse与Rails路径解析不一致,通过末尾斜杠绕过上传路由,Rails在认证前读取文件并经错误响应泄露内容。影响18.7.0至19.3.1版本,修复版本为19.1.8、19.2.6、19.3.2。建议立即升级、限制公网访问并轮换泄露凭据。 综合评分: 88 文章分类: 漏洞分析,WEB安全,安全工具
10分漏洞:GitLab未授权任意文件读取
零日手记 零日手记
随笔漫记安全路
2026年9月12日 09:03 北京
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
9月11日,vulhub提交了CVE-2026-85706的完整复现环境和PoC。这个漏洞允许未认证攻击者读取GitLab服务器上的任意本地文件——不需要登录,只需要目标GitLab上存在一个公开项目。
GitLab CE和EE都受影响。
漏洞根因:Workhorse与Rails的路径理解不一致
GitLab的架构中,Workhorse是前置代理,负责处理大文件上传等请求;Rails是后端应用服务器。漏洞出在两者对同一个URL路径的理解不一致。
关键绕过:末尾斜杠
GitLab Workhorse有一条严格锚定的上传路由,用于匹配/repository/commits。攻击者在路径末尾加一个斜杠——/repository/commits/——Workhorse的严格锚定匹配失败,不把这个请求当作上传请求处理。
但GitLab Rails仍然把这个请求路由到Repository Commits API。
攻击链:
- 攻击者无需认证,查询GitLab的公开项目API,找到一个公开项目
- 向
/api/v4/projects/{project_id}/repository/commits/发送POST请求,Content-Type为application/x-www-form-urlencoded - 请求体中包含
file.path参数,指向服务器上的任意本地路径(如/var/opt/gitlab/gitlab-rails/etc/gitlab.yml) - Workhorse不匹配上传路由,直接转发给Rails
- Rails在认证用户之前先读取该文件
- 如果文件内容包含特殊字符(如百分号序列),触发Rack表单解析器的反射型错误——文件内容出现在HTTP 400响应中
核心问题:Rails在认证之前就读取了文件。 认证是后面才做的,但文件已经读进内存了,内容通过错误响应泄露出来。
PoC分析
vulhub提供的PoC脚本(poc.py)非常简洁:
TARGET_PATH = "/var/opt/gitlab/gitlab-rails/etc/gitlab.yml"
# 1. 无认证查询公开项目
GET /api/v4/projects?visibility=public&simple=true&per_page=100
# 2. 向Commits API末尾加斜杠绕过Workhorse
POST /api/v4/projects/{id}/repository/commits/
Content-Type: application/x-www-form-urlencoded
# 3. 请求体中指定要读取的文件路径
file=&file.path=/var/opt/gitlab/gitlab-rails/etc/gitlab.yml&file.size=1&Content-Type=application/x-www-form-urlencoded
目标文件选择gitlab.yml——这是GitLab Omnibus启动时自动生成的配置文件,包含数据库连接、密钥、SMTP配置等敏感信息。而且这个文件本身包含百分号序列,能触发Rack的反射型解析错误,内容直接出现在HTTP 400响应体中。
内容泄露的条件性
漏洞代码会读取任意可访问路径,但内容是否泄露取决于文件内容:
- 能泄露的文件:内容包含特殊字符序列(如百分号),触发Rack表单解析器的反射型错误,文件内容出现在错误响应中
- 不能泄露的文件:内容能被正常解析(如纯文本
/etc/passwd),文件被读取但不一定出现在响应中
PoC选择gitlab.yml正是因为它是应用原生生成的文件,内容确定能触发泄露——不需要往镜像里塞任何构造数据。
影响版本
| 版本范围 | 受影响 | | — | — | | 18.7.0 – 19.1.7 | 受影响 | | 19.2.0 – 19.2.5 | 受影响 | | 19.3.0 – 19.3.1 | 受影响 |
修复版本:19.1.8、19.2.6、19.3.2。
前置条件
- GitLab版本在受影响范围内
- 目标GitLab上存在至少一个公开项目(公开项目是匿名访问漏洞接口的前提)
- 攻击者能访问GitLab的Web端口(不需要登录)
公开项目这个条件门槛很低——大量GitLab实例用于开源项目托管,默认就有公开项目。
泄露什么有价值
gitlab.yml中包含:
- 数据库连接配置(PostgreSQL主机、端口、数据库名)
- Redis配置
- GitLab密钥(secret_key、otp_key等)
- SMTP邮件配置
- LDAP/SSO配置
- 对象存储配置(S3/OSS密钥)
拿到这些配置信息后,攻击者可以进一步攻击内网数据库、Redis、对象存储,甚至伪造会话Cookie接管管理员账号。
修复建议
- 立即升级到修复版本:19.1.8 / 19.2.6 / 19.3.2
- 如果暂时无法升级,临时缓解:限制GitLab Web端口的公网访问,只允许VPN/内网访问
- 检查
gitlab.yml中的密钥是否曾泄露——如果GitLab曾暴露在公网且有公开项目,假设配置文件已被读取 - 轮换以下凭据:数据库密码、Redis密码、secret_key、对象存储密钥、SMTP密码
- 检查GitLab访问日志中是否有对
/api/v4/projects/*/repository/commits/(注意末尾斜杠)的异常POST请求
参考链接
- GitLab官方补丁发布:docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-2-released/
- 修复commit:gitlab.com/gitlab-org/gitlab/-/commit/0d9ce3e758a85f0690be751e213625f7902c0361
- CVE记录:cve.org/CVERecord?id=CVE-2026-85706
- vulhub复现环境+PoC:github.com/vulhub/vulhub/pull/800
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:随笔漫记安全路 零日手记 零日手记《10分漏洞:GitLab未授权任意文件读取》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论