GitLab惊现高危RCE漏洞:普通用户竟能直接接管服务器?深度解析Oj解析器内存损坏攻击链
2026年6月网络安全研究团队depthfirst抛出了一枚重磅炸弹——他们成功构建了一套针对GitLab的远程代码执行RCE概念验证程序。这个漏洞的可怕之处在于攻击者甚至不需要管理员权限也不需要接触CI流水线只要手里有一个能向项目推送代码的普通账号就能在服务器上以git用户身份执行任意命令。GitLab官方虽然在6月10日悄悄推送了补丁但诡异的是这次修复并没有挂上CVE编号。很多运维人员直到漏洞细节公开才意识到自己管理的自托管GitLab实例可能早已暴露在风险之下。为什么这个漏洞值得所有人警惕往常见到的GitLab漏洞要么需要管理员权限才能触发要么得配合复杂的社工手段。但这次不一样。depthfirst的研究人员明确指出任何经过认证的普通用户只要具备向仓库推送代码的权限就能完整触发整个攻击链。成功利用后恶意代码会在Puma工作进程背后的git账户上下文中运行。这意味着什么攻击者可以顺手牵羊地窃取源代码、Rails应用密钥甚至以此为跳板对内部服务发起横向渗透。源代码泄露、凭证失窃、内网横向移动——这三重威胁叠加在一起足以让任何依赖GitLab托管核心代码的企业夜不能寐。更麻烦的是depthfirst已经在GitHub上公开了完整的PoC利用代码技术门槛被大幅拉低。漏洞根因Jupyter Notebook差异渲染埋下的隐患要理解这个漏洞是怎么形成的得从GitLab处理Jupyter Notebook文件的方式说起。当用户在GitLab中查看.ipynb文件的差异diff时系统内置的ipynbdiffgem会介入处理。这个组件会把仓库中的原始字节直接喂给Puma工作进程里长期运行的Oj::Parser.usual.parse函数。而Oj正是GitLab选用的原生Ruby JSON解析器底层由C语言编写。问题就出在这里攻击者精心构造的恶意JSON数据会绕过Ruby层的安全检查直接进入C语言层面的内存空间。这就像在坚固的城墙上找到了一条通往地下暗河的密道表面看起来风平浪静实则暗流涌动。两个看似无害的Bug串联成致命一击depthfirst发现的攻击链实际上由Oj解析器中的两个内存损坏漏洞共同驱动。单独看这两个Bug都不足以造成实质性危害。第一个漏洞藏在嵌套栈的处理逻辑里。Oj在解析深度嵌套的数组时没有做好边界检查导致数据可以越界写入一个固定大小为1024字节的缓冲区。攻击者利用这一点能够反复向特定内存地址写入单个字节。第二个漏洞则与键长度处理有关。当键名长度被截断到16位时会意外泄露堆指针信息——具体来说是一段固定29字节的数据切片。一个只能重复写一个字节一个只能泄露一小段内存数据。放在平时安全研究员可能扫一眼就过去了。但depthfirst的精妙之处在于他们把这两个小毛病串了起来利用堆指针泄露绕过ASLR地址空间布局随机化再借助可控的写操作篡改回调指针最终调用本地函数完成命令执行。这种积小成大的攻击思路恰恰体现了高水平漏洞研究的精髓。潜伏近五年的定时炸弹让人后背发凉的是时间线。depthfirst的技术文档披露这两个Oj漏洞在解析器中已经沉睡了整整1753天——换算下来接近五年。上游修复之前无数Ruby应用都在不知情的情况下运行着带病的Oj版本。而GitLab中存在漏洞的notebook渲染路径更是从发布之日起就存在了将近四年。四年时间足够这个攻击面被各种自动化扫描工具反复掠过。幸运的是depthfirst报告称目前尚未发现该漏洞在野被利用的迹象。GitLab方面也独立复现了RCE效果确认了漏洞的真实性。披露风波为什么很多运维还没打补丁这次事件还有一个值得玩味的细节。GitLab在6月10日的更新中确实修复了问题维护分支也迁移到了Oj 3.17.3。但《黑客新闻》的跟进报道发现了一个令人费解的操作Oj 3.17.3的版本更新被列在了常规漏洞修复列表里而不是安全更新列表。没有CVE编号没有安全公告的醒目标签很多运维团队自然缺乏紧迫感。反正不是安全补丁晚点升级也无妨——这种心态在缺乏明确安全标识的情况下极易蔓延。对于自托管GitLab的管理员来说这无异于在雷区里散步却浑然不觉。你的GitLab版本在不在危险名单上笔记本渲染器同时存在于GitLab社区版和企业版中订阅级别不影响漏洞是否存在。判断风险的核心标准是实例是否走了Oj的notebook解析路径并且捆绑的Oj版本落在3.13.0到3.17.1之间。具体受影响的GitLab版本如下GitLab CE/EE 15.2.0 到 18.10.7 的版本存在漏洞已在 18.10.8 中修复。GitLab CE/EE 18.11.0 到 18.11.4 的版本存在漏洞已在 18.11.5 中修复。GitLab CE/EE 19.0.0 到 19.0.1 的版本存在漏洞已在 19.0.2 中修复。Oj gem 的 3.13.0 到 3.17.1 版本存在问题已在 3.17.3 中修复。值得一提的是GitLab 15.1 及更早版本在这条路径上使用的是Ruby原生的JSON.parse反而躲过了这一劫。现在该做什么修复与缓解建议对于运行自托管GitLab的运维团队最稳妥的做法就是立即升级到上述修复版本。6月10日的补丁已经将维护分支的Oj依赖升级到了3.17.3详细的版本分支信息可以参考GitLab官方的补丁发布说明。GitLab.com的托管服务已经完成修复使用SaaS版本的用户无需额外操作。专用版Dedicated客户同样不受影响。如果你是通过Helm Chart、Operator或者自定义镜像部署的GitLab判断修复状态的关键指标是Puma Webservice镜像中内置的GitLab版本号而不是看外层包装。由于这次修复没有CVE编号建议各团队直接以Oj gem的版本号作为追踪依据而不是依赖传统的安全标签。可以在Gemfile.lock中确认Oj的版本是否已升级到3.17.3或更高。写在最后这个GitLab RCE案例给整个开源社区敲响了警钟。一个高性能的C语言扩展确实能显著提升Ruby应用的JSON解析效率但当这些原生代码与Web应用的核心渲染路径直接挂钩时任何微小的内存管理疏忽都可能被放大成致命的远程代码执行漏洞。depthfirst的研究不仅展示了一次精妙的漏洞串联利用更暴露了安全披露机制中的灰色地带——没有CVE编号、没有明确的安全标签修复补丁很容易被淹没在常规更新中。对于依赖自托管GitLab的企业而言建立主动的依赖组件版本监控机制或许比等待官方的安全公告更为可靠。