← 开发笔记

GitLab2Shell 响应:CVE-2026-110264 版本检查与升级路径

本文目录

GitLab2Shell 修复意味着将 GitLab CE/EE 升级到修复 CVE-2026-110264 的版本,并验证部署已实际采用。GitLab 10月21日公告说明,在特定条件下,正则表达式编译期间的整数溢出会导致未经身份验证的远程代码执行。仅更新 GitLab Shell 或 Runner,并不能完成 CE/EE 服务器的修复。

先将 CVE 与产品版本对应

本文讨论 GitLab 官方公告中的 CVE-2026-110264,评分为 10.0(CVSS v3.1)。应将它与同期发布的其他 GitLab CVE 及名称相近的 Shell 组件区分开。GitLab 编写的 CVE 记录记载了相同的受影响范围和修复门槛。

GitLab CE/EE 分支 首个修复此 CVE 的版本
18.11 18.11.13
19.0 19.0.10
19.1 19.1.9
19.2 19.2.9
19.3 19.3.6
19.4 19.4.3
19.5 19.5.1

公告将从 7.0 起、低于 18.11.13 的版本,以及表中每个分支低于首个修复版本的版本列为受影响。此表于 2026年10月30日核对,给出的是首个修复门槛,不是固定不变的最新安装版本清单。公告对 GitLab.com 和 GitLab Dedicated 单独提供采用情况信息;不要将 Self-Managed 升级说明不加区分地应用于这些服务。

离线比较声明的版本字符串

解析稳定发行版版本号,按数值比较其分支门槛,同时保留部署未验证状态

图示对应下面的比较代码。先验证输入,再比较已登记的分支。较旧的受影响分支需要规划升级路径;表外分支保持未知。任何结果都不能认证服务器状态或补丁来源。

使用 Python 3.11 或更高版本,将此文件保存在新目录中。它辅助对官方上游 CE/EE 发行版版本号进行数值比较,不发送网络请求、不发现服务,也不执行利用。接受 19.5.1、19.5.1-ee 和 19.5.1-ee.0 等形式;不会猜测预发布版、nightly 或供应商自定义版本格式。

release-threshold.py

import re
import sys

FIRST_FIX = {
    (18, 11): 13,
    (19, 0): 10,
    (19, 1): 9,
    (19, 2): 9,
    (19, 3): 6,
    (19, 4): 3,
    (19, 5): 1,
}
NUMBER = r"(0|[1-9][0-9]{0,2})"
VERSION = rf"{NUMBER}\.{NUMBER}\.{NUMBER}(?:-(?:ce|ee)(?:\.[0-9]{{1,3}})?)?"


def main(argv):
    match = re.fullmatch(VERSION, argv[1]) if len(argv) == 2 else None
    if match is None:
        print("usage: release-threshold.py VERSION (stable CE/EE release format)", file=sys.stderr)
        return 2
    major, minor, patch = map(int, match.groups())
    branch = (major, minor)
    if branch in FIRST_FIX:
        baseline = f"{major}.{minor}.{FIRST_FIX[branch]}"
        state = "met" if patch >= FIRST_FIX[branch] else "below"
        status = 0 if state == "met" else 1
    elif (7, 0) <= branch < (18, 11):
        baseline, state, status = "upgrade-path-required", "below", 1
    else:
        baseline, state, status = "not-covered", "outside-table", 2
    print(f"release-threshold={state}")
    print(f"baseline={baseline}")
    print("deployment-and-release-provenance=not-verified")
    return status


if __name__ == "__main__":
    raise SystemExit(main(sys.argv))
python3 release-threshold.py 19.5.1-ee.0

本地运行返回了以下输出,退出状态为 0。

release-threshold=met
baseline=19.5.1
deployment-and-release-provenance=not-verified

状态 0 仅表示提供的数字达到此 CVE 公布的修复门槛。状态 1 表示低于公布门槛;状态 2 表示格式不受支持,或分支不在表中。它不检查发行版是否存在、软件包是否官方发布,也不检查是否有节点在运行它。回移补丁与自定义构建需要另行提供供应商补丁证据。

将安装证据与运行采用关联起来

官方维护文档说明,Linux 软件包可用 sudo gitlab-rake gitlab:env:info,源码安装可用 bundle exec rake gitlab:env:info RAILS_ENV=production,收集 GitLab、Ruby 和组件信息。多节点部署应在承载 Rails 的节点上执行。输出可能包含内部路径与地址,应保存在访问受限的运维记录中。

本文没有在生产服务器上执行这些命令。实际修复时,应将信息与完整软件包修订号、已部署镜像摘要以及每个 Web/后台节点关联,并在升级后验证所有目标都已采用。一个 HTTP banner 或另一个节点的命令输出,不能作为整个部署的证据。

选择当前补丁并完成迁移

从已安装版本出发,遵循官方升级路径,在每个必要的停靠点等待后台迁移完成,再继续下一步。旧安装可能不支持直接跳到表中最高版本。应统一规划备份与恢复、扩展兼容性、停机及多节点流程。

区分首个修复与当前补丁。10月29日补丁公告列出了包括 19.5.3 和 19.4.5 在内的后续版本以及部分数据库迁移,并明确说明跳过了 19.5.2 和 19.4.4。脚本不查询发行版目录,因此对这些字符串也会进行数值比较。实际安装候选版本始终应从官方分发记录中选择。

升级后,分别检查运行版本、迁移完成情况、正常登录、仓库访问及任务处理。公告提到的 Onigmo 工作进程崩溃和 Org-mode 渲染错误突发检测是调查线索;任何一项单独出现都不能证明或排除入侵。如果怀疑入侵,请保留日志、进程及部署证据,并单独调查。

同期的 Java 证书修复是另一项问题。对于使用 JDK 的构建与集成服务,也请阅读 eMudhra 与 JVM 信任库检查。

讨论