文章总结: 文档分析CVE-2026-44592漏洞(CVSS9.4),揭示GradientCI系统在默认配置下因Worker注册机制完全缺失认证,允许攻击者通过未注册UUID获得Nix构建缓存写入权限,导致供应链投毒风险。关键发现包括攻击者可注入恶意代码污染缓存、影响下游构建项目,并提供立即升级至v1.1.1、禁用DISCOVERABLE模式及网络隔离等修复建议。 综合评分: 92 文章分类: 漏洞分析,供应链安全,云安全,解决方案,安全建设
UUID 即通行证:Gradient CI 未认证 Worker 注册与供应链投毒威胁
原创
CVE-SEC CVE-SEC
CVE-SEC
2026年5月15日 13:00 中国台湾
在小说阅读器读本章
去阅读
UUID 即通行证:Gradient CI 未认证 Worker 注册与供应链投毒威胁
前言
供应链攻击的核心逻辑是”污染上游,影响下游”。当攻击者无法直接攻破目标系统时,他们会寻找目标所依赖的基础设施——构建系统、包仓库、依赖缓存——将恶意代码注入其中,让目标在正常的构建和部署流程中自动”引进”攻击者的代码。
CVE-2026-44592 提供了这样一条路径。Gradient 是面向 Nix 生态的持续集成系统,其 Worker 注册机制在默认配置下完全省略了认证要求:任何能够访问 /proto 端点的实体,只需提供一个从未注册过的 UUID,即可成为合法的 Worker 节点,获得写入 Nix 构建缓存的权限。
CVSS 评分 9.4,CWE-306(关键功能缺少认证),这个漏洞的危害不在于技术复杂性,而在于它所开放的攻击面:一个注册成功的恶意 Worker,可以将任意内容写入 Gradient 的 Nix store 缓存,使所有依赖该缓存的构建项目包含攻击者植入的代码。
Gradient 与 Nix 生态的特殊性
要理解 CVE-2026-44592 的危害,首先需要理解 Nix 生态中”构建可重现性”这一核心概念的安全含义。
Nix 的核心设计哲学是确定性构建:给定相同的输入(源代码、依赖版本、构建环境),必然产生相同的输出。这种确定性通过内容寻址(content-addressed)的 Nix store 实现——每个构建产物(package)由其内容的加密哈希唯一标识,存储在 /nix/store/ 中。
Nix 的二进制缓存(binary cache)机制允许团队跳过重复构建:若某个 store path 对应的构建产物已在缓存中存在,Nix 直接从缓存下载而不重新构建。这显著加快了 CI/CD 流程,但也引入了一个关键的信任假设:缓存中的内容必须与对应 store path 的内容一致。
Gradient 作为 CI 系统,维护了一个 Nix 构建缓存(通过 nar_storage 和 cached_path 数据表管理)。Worker 节点执行构建任务后,将产生的 NAR(Nix Archive)文件上传至此缓存,供后续构建下载复用。
CVE-2026-44592 的攻击目标正是这个缓存机制:通过未认证 Worker 注册获得写入权限,上传伪造的 NAR 文件,使缓存中某个 store path 对应的内容被替换为攻击者控制的恶意内容。当合法的构建任务从缓存获取这个 store path 时,它得到的是攻击者植入的代码,而不是正常的构建产物。
漏洞技术分析:认证的完全缺失
Gradient 通过 GRADIENT_DISCOVERABLE 配置项控制 Worker 自动发现机制。当该选项设置为 true 时(这是 NixOS 官方模块的默认值),新 Worker 可以通过以下流程自我注册:
- 向
/proto端点发送注册请求,携带一个 Worker UUID - 服务端查询数据库,检查该 UUID 是否已存在
- 若 UUID 不存在(即”新 UUID”),服务端将其注册为合法 Worker
- 注册成功,该会话获得
PeerAuth::Open权限级别
这个流程的根本问题在于步骤 3 的判断逻辑:服务端将”UUID 未被注册过”等同于”这是一个合法的新 Worker 首次连接”,并据此赋予完整权限。
UUID 是一种用于在系统内唯一标识实体的标识符格式,其设计目的是唯一性,而非保密性或认证性。一个 UUID 是否曾经被注册,不能作为判断其持有者是否具有合法身份的依据。任何人都可以生成一个随机 UUID,而 UUID 的空间足够大(2^122 种可能),生成一个从未被注册过的 UUID 几乎是确定的。
PeerAuth::Open 权限的危害范围
注册成功后获得的 PeerAuth::Open 权限级别,提供了比 Worker 正常工作所需更宽泛的访问能力:
跨组织构建任务可见性:具有此权限的 Worker 可以查看系统中所有组织的构建任务,包括任务配置、源代码仓库地址、分支信息、构建参数、环境变量。对于托管多个客户的 Gradient 实例,这意味着客户之间的信息隔离完全失效。
NarPush 操作:向 nar_storage 写入任意 NAR 文件,即向 Gradient 的构建缓存上传内容。
NarUploaded 操作:向 cached_path 表写入 Nix store 路径与缓存内容的映射记录,即更新缓存索引,将特定 store path 关联到攻击者上传的 NAR 文件。
NarPush 与 NarUploaded 的组合,是供应链攻击的完整路径:上传恶意内容,然后修改索引,使正常的 store path 指向恶意内容。
供应链攻击的完整步骤
以下是一个概念性的攻击流程,描述漏洞被利用于供应链投毒的完整路径:
第一步:注册恶意 Worker
攻击者生成一个随机 UUID,向 Gradient 的 /proto 端点发送 Worker 注册请求。由于系统未进行任何认证,注册立即成功,攻击者获得 PeerAuth::Open 权限。
第二步:侦察目标构建依赖
利用 PeerAuth::Open 权限枚举所有组织的构建任务,识别目标组织依赖的 Nix store 路径。攻击者需要确定哪些 store path 是目标经常使用的依赖,这是供应链攻击的目标定位阶段。
第三步:构造恶意 NAR 文件
Nix Archive(NAR)格式是 Nix store path 内容的序列化表示。攻击者构造一个 NAR 文件,其内容在视觉上或功能上与合法版本相似(以避免被立即发现),但包含植入的恶意代码——例如,在某个脚本中添加后门、修改配置文件以建立持久化、或在编译器/工具链中植入编译时恶意代码注入。
第四步:污染缓存
通过 NarPush 操作将恶意 NAR 文件上传至 nar_storage,然后通过 NarUploaded 操作将目标 store path 的 cached_path 记录更新为指向这个恶意 NAR 文件。
第五步:等待构建触发
目标组织的下一次构建启动时,Nix 客户端发现对应的 store path 在 Gradient 缓存中存在记录,直接从缓存下载而不重新构建(这是 Nix 缓存的正常行为)。下载到的是攻击者植入的恶意 NAR 文件,其中的代码在构建环境中执行。
第六步:扩散与持久化
若构建产物被打包进 Docker 镜像、发布为软件包,或部署至生产环境,恶意代码随之传播,影响范围进一步扩大。
默认配置即为漏洞:安全设计的根本失误
CVE-2026-44592 的一个特别值得关注的方面是:漏洞的触发条件——GRADIENT_DISCOVERABLE=true——是 NixOS 官方模块的默认配置。
这意味着按照官方文档、使用 NixOS 模块部署 Gradient 的用户,在未意识到任何安全风险的情况下,其实例默认就处于受影响状态。他们甚至不需要做任何”错误”配置——遵循默认值就足以触发这个 9.4 分的漏洞。
DISCOVERABLE 功能的设计初衷可以理解:简化 Worker 的接入流程,无需管理员手动预配置每一个 Worker 节点,实现 Worker 的自动注册和动态扩展。这在受控的私有网络环境中可能是合理的便利功能。
但问题在于,设计者将”简化部署”与”省略认证”混为一谈。简化部署可以通过更轻量的认证机制实现(如预共享令牌、基于时间的一次性密码、证书自动颁发),而非完全移除认证。将认证完全省略,意味着一旦 /proto 端点可被未授权网络访问,安全边界立即瓦解。
漏洞的实际利用条件
必要条件:攻击者能够访问 Gradient 的 /proto 端点(通常是 gRPC 端口)。
常见暴露场景:
- Gradient 部署在公网可达的服务器上,未通过防火墙限制
/proto端口的访问 - 攻击者处于目标 Gradient 实例所在的内网(例如,通过其他漏洞获得内网访问权限)
- CI/CD 环境中,多个团队共用一个 Gradient 实例,内部人员可能滥用此漏洞
不存在的门槛:
- 无需任何账户或密码
- 无需任何特殊工具,标准的 gRPC 客户端即可
- 无需了解目标的任何配置信息
检测与审计
配置审计是最简单的检测方式:
# 检查 GRADIENT_DISCOVERABLE 配置
systemctl show gradient | grep -i discoverable
# NixOS 系统
nixos-option services.gradient.discoverable
若 GRADIENT_DISCOVERABLE=true 且 /proto 端口对外可达,该实例处于受影响状态。
Worker 注册记录审计:检查 Gradient 数据库中的 Worker 注册记录,与已知合法 Worker 列表对比,识别未知 UUID:
# 检查 Gradient 日志中的 Worker 注册事件
journalctl -u gradient | grep -i "worker\|register\|peer\|auth" | head -100
任何未被识别的 Worker UUID 都应视为可疑。
NAR 缓存完整性验证:在升级前后,建立 nar_storage 内容的快照并进行哈希验证。检查 cached_path 表中是否存在与预期不符的记录,特别是最近修改时间与正常构建时间不对应的记录。
网络层监控:监控 Gradient /proto 端口的访问来源 IP,检测非预期地址的连接尝试。
修复与防护
立即升级至 Gradient v1.1.1 是唯一可靠的修复措施。v1.1.1 在 Worker 注册流程中引入了认证要求,不再允许仅凭未注册 UUID 完成注册。
升级前的临时缓解:
# 临时禁用 DISCOVERABLE 模式
GRADIENT_DISCOVERABLE=false ./gradient serve
# 或在 NixOS 配置中
services.gradient.discoverable = false;
禁用后,新 Worker 无法自动注册,需要管理员手动配置。这会影响 Worker 的动态扩展能力,但可以立即消除未认证注册的攻击面。
网络层防护:限制 /proto 端口(通常是 gRPC 默认端口 50051 或自定义端口)的访问,仅允许来自已知 Worker IP 地址的连接:
# iptables 规则示例
iptables -A INPUT -p tcp --dport <proto-port> -s <trusted-worker-ip>/32 -j ACCEPT
iptables -A INPUT -p tcp --dport <proto-port> -j DROP
NAR 签名验证:Nix 支持对 NAR 文件进行签名验证(通过 nix.conf 中的 trusted-public-keys 配置)。配置要求从 Gradient 缓存下载的 NAR 文件必须携带由受信任密钥签名的签名,可以作为额外的完整性保护层,即便缓存内容被污染,未携带有效签名的恶意 NAR 也无法被下载和安装。
对 CI/CD 系统安全的普遍启示
CVE-2026-44592 提出了一个值得所有 CI/CD 平台开发者和使用者思考的问题:构建系统的信任边界在哪里?
在现代软件开发实践中,CI/CD 系统处于软件供应链的核心位置:它从版本控制系统拉取代码,调用包管理器获取依赖,执行构建和测试,将产物推送到制品仓库,最终触发部署。整个链路中,CI 系统所信任的每一个数据源,都是潜在的攻击入口。
Gradient 的案例揭示了一个特别敏感的信任关系:Nix 构建缓存。当 CI 系统信任某个缓存源的内容时,该缓存的写入权限就成为了整个供应链的关键控制点。任何能够写入该缓存的实体,都能够影响所有依赖该缓存的构建产物。
这要求构建缓存的写入权限必须受到严格的认证和授权控制,认证强度应当与缓存内容对下游系统的信任影响相匹配。”默认允许自动注册”的 DISCOVERABLE 模式,在设计上就低估了缓存写入权限的安全敏感性。
总结
CVE-2026-44592 是一个”设计即为漏洞”的案例:Worker 自动发现功能以简化部署为目标,将”省略认证”当作”简化认证”,在默认配置下向任何网络可达实体开放了 Nix 构建缓存的写入权限。
漏洞的 CVSS 评分 9.4 准确反映了其供应链危害潜力:一个成功注册的恶意 Worker,可以在不修改任何源代码、不触发任何代码审查、不引发任何警报的情况下,将恶意代码注入依赖该 Gradient 实例的所有项目的构建产物中。
对于所有使用 Gradient 的团队,应立即升级至 v1.1.1,同时对现有 Worker 注册记录和 NAR 缓存内容进行完整性审计,确认在漏洞存在期间没有未授权的 Worker 注册和缓存写入事件。在 CI/CD 安全日益成为攻防焦点的今天,构建缓存的完整性保护需要被列为与密钥管理同等重要的安全控制项。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:CVE-SEC CVE-SEC CVE-SEC《UUID 即通行证:Gradient CI 未认证 Worker 注册与供应链投毒威胁》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论