文章总结: 本文深度解析GitLabCVE-2026-85706漏洞,该漏洞为未认证任意本地文件读取,CVSS满分10.0,影响18.7至19.3.1版本。根因是端点缺失认证、信任客户端可控file.path参数及错误回显叠加。建议立即升级至19.1.8/19.2.6/19.3.2,并附非破坏性检测脚本。 综合评分: 95 文章分类: 漏洞分析,应急响应,安全建设,解决方案,安全工具
GitLab满分漏洞:一个API无需账号读穿整台服务器(CVE-2026-85706,附PoC)
原创
赤霄攻防实验室 赤霄攻防实验室
赤霄攻防实验室
2026年9月12日 12:00 江苏
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
TL;DR
是什么:GitLab 自建版(CE/EE)repository commits / files API 存在未认证任意本地文件读取(CVE-2026-85706),CVSS 3.1 满分 10.0,无需任何账号;
影响面:18.7 ~ 19.3.1 全部自建实例,官方 9 月 10 日一次性修复 18 个漏洞,强烈建议立即升级;
根因:端点缺失用户认证 + 信任客户端可伪造的 file.path 参数(而非中间件落盘对象)+ 解析错误回显文件内容,三重缺陷叠加;
看点:本文基于官方安全修复 commit 0ff7b6b 逐行还原根因与攻击链,并已开源非破坏性检测脚本(文末「参考」附 PoC 链接,判定式仅用状态码,不读取不外传任何文件内容)。
漏洞编号CVE-2026-85706(GitLab 内部 issue #627748)
危害等级严重(满分) CVSS 3.1:10.0(AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
漏洞类型路径信任错位 + 认证缺失 → 未认证任意文件读取(CWE-22 / CWE-862)
影响产品GitLab CE/EE 自建实例 18.7 ~ 19.1.7 / 19.2.0 ~ 19.2.5 / 19.3.0 ~ 19.3.1
在野状态暂无公开在野利用与公开 PoC(GitLab 官方确认);watchvuln 奇安信 CERT 已验证
修复版本19.1.8 / 19.2.6 / 19.3.2(2026-09-10 补丁发布,共 18 项修复)
报告来源安全研究员 s3ntago(HackerOne 众测平台)
背景:满分洞为什么出现在「建仓库」的 API 上
GitLab 的 commits API 支持一次请求创建多个文件的提交。当请求体较大时,架构上由反向代理组件 Workhorse 先把请求体缓冲落盘为临时文件,再交给 Rails 主应用解析——这是为绕过 Rails 对大请求体处理效率的不足而设计的「正文上传」机制。
问题恰恰出在这条「代理先行」的路径上:解析临时文件时,代码读取的是请求参数里的 file.path 与 file.size,而不是 Workhorse 真正落盘后交给 Rails 的标准 UploadedFile 对象。前者完全由客户端控制,后者才是服务端中间件的产物。信任了错误的来源,等于把「读哪个文件」的决定权交给了攻击者。
更糟的是,这些端点在校验内部代理 JWT 之外完全没有用户身份校验——也就是说,一个连账号都不需要注册的匿名请求,就能驱动服务端去读任意本地文件。
▲ 攻击链还原:三重缺陷叠加成满分洞(基于修复 commit 实证)
根因深挖:修复 commit 逐行对照
GitLab 的安全修复默认先合入私有 security 仓库,90 天后才公开细节。但补丁发布当天,backport 分支的提交已经随版本仓库放出。本次修复 commit(0ff7b6b,分支名 security-627748-workhorsefile-lfi)在三个端点同时动了刀:
其一,三个端点全部补上用户身份校验调用,未认证请求从此在进入业务逻辑前就被拦截,官方回归测试明确要求「未认证用户访问公开项目的上传授权端点必须返回 401」。
其二,也是最核心的:解析逻辑改为只接受中间件落盘生成的 UploadedFile 类型对象,类型不符直接报错。客户端伪造的 file.path 字符串从此不再被当作文件路径使用——修复注释写得直白:「只信任中间件最终确认的上传元数据,绝不信任原始 file.path / file.size 参数」。
其三,解析异常的错误处理中移除了将底层异常信息拼入响应的写法。这一点别有深意:修复测试专门构造了一个金丝雀字符串写入服务器本地文件,验证漏洞版本的错误响应会携带文件内容片段外泄——这正是把「任意文件读取」变成「可回显读取」的最后一环。
▲ 修复前后逻辑对照(整理自安全修复 commit 0ff7b6b2)
能读什么:从文件读取到供应链失守
任意本地文件读取在 GitLab 这种全家桶架构下危害被急剧放大。Omnibus 一体化部署把数据库配置、邮件凭据、对象存储密钥全部写在本地配置文件里;更致命的是 gitlab-secrets 密钥文件——它加密着实例的全部 CI/CD 变量与令牌。拿到它,攻击者就能离线解密所有项目的流水线密钥,从「读一个文件」升级为「接管 Runner、污染构建产物」,源码供应链全线失守。这也是官方给出 C:H/I:H/S:C(范围改变)满分向量的原因:伤害越过了 GitLab 组件本身。
利用前提只有两条:目标经标准 Workhorse 反代暴露(默认部署即满足),且文件对 Rails 进程可读(服务进程权限通常足够)。官方通告中「在一定条件下」的措辞,对应的正是这些部署形态约束。
▲ GitLab 官方安全通告:CVSS 10.0,建议全部自建实例立即升级
▲ 修复 commit:「Fix unauthenticated arbitrary local file read in commits API」
修复与自查
官方无临时缓解措施,唯一解是升级。版本对照如下:
▲ 版本矩阵(数据来源:GitLab 官方安全通告)
自查两条路:管理后台 Help 菜单看版本号是否在修复线之上;或用检测脚本对实例发一个不带任何凭据的探测请求——修复版返回 401,漏洞版会返回带特定错误短语的业务响应。检测脚本已开源,判定只依赖状态码与固定短语,不读取、不展示、不外传任何文件内容,可直接用于授权资产盘点。
另注意本次补丁日同车修复的 CVE-2026-87719(GraphQL 订阅反序列化,9.9 分,可获取实例敏感配置与凭据)与 CVE-2026-88765(Unicode 转换缓冲区溢出,8.5 分,导入恶意项目导出可 RCE)——升级一次全解决,没有只升一半的理由。
▲ NVD 收录页
防御视角:两个低成本错误的乘法
复盘这个漏洞,没有一处高深的技术:忘加一行认证、多信了一个客户端参数、错误处理多回显了一段异常详情——三个各自不起眼的疏漏相乘,就是满分。对自研系统的启发有三:代理/中间件与业务代码的「信任边界」要有显式类型契约(只信中间件产物对象,不信请求参数自述);错误响应永远不要透传底层异常原文;新增「内部机制端点」时把「是否需要认证」作为默认检查项而不是事后补救项。
参考
· GitLab 官方安全通告:docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-2-released
· 修复 commit:gitlab.com/gitlab-org/gitlab/-/commit/0ff7b6b2911
· NVD:nvd.nist.gov/vuln/detail/CVE-2026-85706
· BleepingComputer 报道:bleepingcomputer.com/news/security/gitlab-urges-users-to-patch-max-severity-path-traversal-flaw
· 非破坏性检测脚本(附PoC):https://github.com/Rubby2001/CVE-POCS/tree/main/CVE-2026-85706
我是赤霄攻防实验室,每晚精选一个高价值漏洞做深度拆解。本篇基于官方修复 commit 一手分析,全部技术细节可溯源。检测脚本仅限授权测试使用。 如果这篇对你有帮助,点个「在看」并转给管 GitLab 的同事——升级别过周末。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赤霄攻防实验室 赤霄攻防实验室 赤霄攻防实验室《GitLab满分漏洞:一个API无需账号读穿整台服务器(CVE-2026-85706,附PoC)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论