我们在本书中一路从 SCM 到持续集成与交付(CI/CD)讨论交付流程时,曾多次提及安全工具与实践。我们谈到,现代工具中的 RBAC(基于角色的访问控制)与 Policy-as-Code(PaC,策略即代码)治理如何帮助保护你的代码仓库与流水线,也提到在持续集成阶段开展早期安全测试的作用;我们还考察了用于发现应用在运行时漏洞的动态测试。迄今为止,这些对安全的讨论都比较轻描淡写。
本章将把安全放到聚光灯下,给予其在当今网络攻击频率与复杂度不断提升的世界里应有的关注。重大泄露事件频频登上头条,全球监管日益收紧,客户也越来越多地根据厂商的安全态势来进行评估。
当发布节奏以“天”而非“月”计时,把安全作为投产前最后一道关口的传统模式已难以为继。取而代之的是,我们把负担“左移”到开发者身上,要求他们把安全实践融入日常工作流。并非安全专家的开发者,如今承担着前所未有的安全责任。
人工智能有望缓解这种紧张关系。由 AI 驱动的安全工具正在提升检测准确度,大幅减少浪费开发者时间的误报,甚至能够自动生成修复代码。AI 并非只是简单地把安全负担左移,而是帮助分担这份负担,为开发者提供专家级的安全指引,而无需他们自己成为安全专家。
本章将阐述向 AI-native(AI 原生)软件交付演进如何从根本上改变我们处理安全问题的方式——不是单纯叠加更多工具或流程,而是改变我们识别、优先级排序与修复安全问题的根本方法。我们还将讨论软件供应链安全的重要性:保护从最初编写代码到产出最终产品这一整条构建与交付链上的工具、流程与人员。随着现代软件高度依赖相互连接的组件,每个环节都可能存在被恶意行为者利用的漏洞,这一点尤为关键。
理解供应链方面的关注点,并学会以安全视角审视你的 SDLC(软件开发生命周期),将使你能够部署强有力的安全措施,更好地保护你的应用、数据以及组织声誉。
现代应用与网络威胁态势
构建与部署现代软件应用高度依赖分布式且复杂的软件供应链。这些供应链往往涵盖庞大的代码仓库网络、开源依赖、第三方组件、制品库以及 CI/CD 流水线。虽然这种互联互通催生了创新并加速了开发周期,但也在每个环节引入了安全风险。不断扩大的攻击面,以及漏洞在供应链中传播的可能性,使我们的软件供应链成为恶意行为者的首要目标。
在本节中,我们将审视这些威胁,并了解用于规范软件供应链的合规框架如何演进以应对它们。最后,我们将看看新的合规要求如何影响你的组织。
日益增长的软件供应链攻击威胁
软件供应链涵盖了创建与交付软件过程中涉及的所有人员、流程与工具。它跨越软件开发的完整生命周期,从最初的代码创建到部署与维护。这是一个复杂的生态系统,其中每个要素都在最终产品中扮演关键角色。
软件供应链主要由两个关注点构成:应用程序与 DevOps 工具链,如图 5-1 所示。
软件供应链中的应用风险
这里的“应用程序”指的是你软件的所有组成要素,包括你的专有源代码;开源依赖(例如库、框架和模块);以及开发过程中产出的软件制品。
根据 Synopsys 发布的 2024 年《Open Source Security and Risk Analysis(开源安全与风险分析)》报告,96% 的代码库包含开源组件。需要牢记的一点是,我们的组织对所使用的开源组件的安全负责,就像对内部开发代码的安全负责一样。由于开源使用如此广泛,应用中发现的漏洞有 80% 以上来自开源依赖也就不足为奇了。一个由开源引入威胁的例子是 2021 年在一款广泛使用的 Java 日志库 Log4j 中发现的漏洞。该漏洞允许攻击者仅通过向应用日志发送特制字符串,就能在受影响系统上远程执行代码。由于 Log4j 在应用和服务中的普遍使用,此漏洞极其危险,促使业界大规模紧急打补丁并采取缓解措施。
在广泛使用的数据压缩工具 XZ Utils 中发现后门,提供了另一个例子。XZ Utils 与许多开源项目一样,由志愿者维护,资源有限,难以及时处理安全问题。结果发现,一名受信任的贡献者实现了一个后门,可能让攻击者在使用该工具构建的软件所运行的系统上获取管理员权限。该工具存在于大多数 Linux 发行版中;所幸在其被大规模部署到生产系统之前就被发现了。
应用供应链中的另一个新兴威胁利用了 AI 编码助手的“幻觉”。当 AI 模型“幻觉”出包名,推荐不存在的库或错误的包标识时,就为攻击者创造了机会。恶意行为者可以监控流行的 AI 编码助手是否出现这类“幻觉”,随后在公共仓库中注册这些“幻觉”出的包名。当开发者尝试使用这些并不存在、但被 AI 推荐的包时,就会在不知情的情况下安装恶意代码。这种“幻觉抢注”(hallucination squatting)的攻击途径已在现实中被观察到;研究人员发现,常见的编码助手频繁建议并不存在的包。
软件供应链中的 DevOps 风险
DevOps 工具链包括用于自动化软件构建、测试和部署的一整套工具与流程。这涵盖代码仓库、CI/CD 工具与流水线、制品仓库,以及其他简化开发流程的工具,如 GitOps 和 IaCM 工具。
SolarWinds 攻击是一个鲜明的例子,展示了受损的 DevOps 工具链如何被用来传播恶意代码。在这次复杂的攻击中,威胁参与者潜入了 SolarWinds Orion 的软件构建系统,将恶意代码注入合法的软件更新中。随后,这些被污染的更新被分发给 1.8 万家 SolarWinds 客户,使攻击者获得对其网络的广泛访问权。该事件凸显了攻击者如何利用 DevOps 流水线固有的信任与自动化,在规模上分发恶意软件,把一次常规的软件更新变成毁灭性的网络攻击。
2021 年的 Codecov 供应链攻击是另一起工具链安全失陷的案例,影响了数千家组织。恶意行为者修改了 Codecov 的 Bash Uploader 脚本(客户用于上传代码覆盖率数据的工具)。这一修改使攻击者能够从 Codecov 客户的持续集成环境中外传敏感信息,如令牌、密钥和凭据。此次入侵在两个多月内未被发现,可能暴露了存放在客户持续集成环境中的敏感数据。
不断增长的威胁
软件供应链攻击不会消失。Gartner 研究预测,到 2025 年,全球将有 45% 的组织遭遇针对其软件供应链的攻击。无论是一行代码中的安全缺陷、某个第三方库的问题,还是流水线中的某个工具,都可能产生连锁反应,危及整个软件产品。保护软件供应链不仅是保护单个组件,更在于保障整个开发与交付过程的完整性与安全性。
适用于软件供应链的合规与监管框架
鉴于威胁不断上升,各国政府与监管机构以相关法规作出回应,旨在通过确立最佳实践、促进透明度,并要求组织采取主动措施来保障其软件供应链安全,从而应对这些挑战。以下是出现的一些最重要的合规与监管框架:
- United States Executive Order 14028, Improving the Nation’s Cybersecurity(美国总统行政令第 14028 号:提升国家网络安全)
该行政令于 2021 年发布,要求联邦机构及其软件供应商强化软件供应链安全实践。其强调采用安全的软件开发实践、漏洞披露与事件响应。 - The European Union’s Network and Information Security 2 Directive(NIS2 指令,欧盟网络与信息安全指令 2)
该指令旨在在欧盟范围内建立较高且一致的网络安全水平。其包含关于软件供应链安全的规定,要求组织评估并管理与软件组件和第三方依赖相关的风险。 - NIST SP 800-218, Secure Software Development Framework(SSDF,安全软件开发框架)
美国国家标准与技术研究院(NIST)发布的该文档为在 SDLC 中整合安全(包括供应链风险管理)提供指导,给出了全面的安全软件开发实践框架。 - ISO/IEC 27036-2:2023
该标准为与供应商及供应链相关的信息安全风险管理提供指南,涵盖供应商选择、合同管理与绩效监控等方面。 - Payment Card Industry Data Security Standard(PCI DSS,支付卡行业数据安全标准)
虽然并非专门针对软件供应链,但 PCI DSS 要求处理支付卡数据的组织实施安全的软件开发实践,其中包括对供应链风险的管理。 - Cyber Resilience Act(CRA,网络韧性法案)
这是一项欧盟拟议法规,旨在提升数字产品与服务的网络安全。其要求包括漏洞处理、安全更新、软件物料清单(SBOM),以及在知悉后 24 小时内报告正在被积极利用的漏洞。
此外,Quality System Regulation(QSR,质量体系法规,21 CFR Part 820) 与 General Data Protection Regulation(GDPR,通用数据保护条例) 也是规范软件实践、并间接影响软件供应链问题的框架。QSR 要求对医疗器械(包括其中的软件组件)实施严格的控制与流程,以确保其安全性与有效性,这包括要求制造商对集成到其设备中的软件进行验证与控制。类似地,GDPR 对个人数据保护的严格要求,迫使组织实施强有力的技术和组织措施,这些措施可能扩展到软件及其供应链的安全,尤其当软件处理个人数据时。
这些框架与法规共同促进了更安全、更具韧性的软件生态系统,既有利于企业,也有利于消费者。但其带来的复杂性也会影响开发团队。理解这些要求并将其融入你的流程,对成功实现合规至关重要。
通过左移保障现代应用程序安全
面对高度有动力的黑客,传统的“等到最后再做安全”的方法远远不够。这些措施不仅无法提供我们所需的防护,传统的安全测试还会减慢软件交付。要保护现代应用程序,组织必须采用为现代 DevOps 工作流而设计的工具与实践。本节将审视组织在落实安全实践时面临的挑战。在第 3 章中我们提到了 shift-left security,即在开发最早阶段实施安全实践的做法。我们将探讨如何利用这种方法来缓解风险,以及在开发者友好的前提下实施左移安全与管理漏洞的最佳实践。
面向开发者友好的左移安全的必要性
与其在软件开发周期的末尾才测试应用的安全性,不如在每一个可能的阶段主动处理与测试安全问题。这种方法不仅通过避免在后期对代码进行大规模返工来节省时间和精力,还能提升最终产品的整体安全性与效率。图 5-2 对比了左移安全方法与传统的应用安全方法。
需要注意的是,有效的左移安全不只是把安全测试提前到交付流程的更早阶段。尽管这有助于减少开发者在数天或数周后回到同一段代码时的上下文切换成本,但它本质上并没有减少工作量。真正有效的实施需要选择能与 CI/CD 流水线无缝集成的安全工具。这些工具不仅应当识别漏洞,还应按严重性进行优先级排序,并提供可执行的洞见。你选择的工具应当对发现结果进行规范化与去重,帮助开发者避免告警疲劳,把精力集中在最关键的风险上。这种集成式方法确保安全在开发过程中处于绝对核心的位置。
图 5-2. 左移方法与传统测试方法的对比
应用程序安全扫描器
用于进行安全测试与分析的扫描器与工具种类众多,而且许多现在都增强了 AI 能力。下面来看最常见的类别:
-
Software composition analysis(SCA)
通过分析软件物料清单(SBOM),识别第三方组件与依赖中的漏洞,以检测库与框架中的已知漏洞。我们将在本章后面讨论 SBOM。SCA 工具在“漏洞可达/可被利用的可能性”方面具备显著的机器学习能力。Snyk 是常见的 SCA 扫描器之一。 -
Static application security testing(SAST)
无需执行应用即可分析源代码中的潜在漏洞,通过扫描代码中指示漏洞的模式(如 SQL 注入、XSS、缓冲区溢出)。AI 正在增强 SAST,以降低误报率,减少工程师的时间浪费。SonarQube、Checkmarx、Fortify 是 SAST 工具的示例。 -
**Container scanning **
通过分析容器镜像内容来识别容器镜像及其依赖中的已知漏洞与配置错误。
-
Secret detection scanning
在代码仓库与配置文件中检测敏感信息,如 API 密钥、密码与令牌。借助 AI,密钥检测工具在识别混淆过的密钥以及区分真实凭据与测试数据方面的能力更强,从而降低误报与相关的人力消耗。 -
Dynamic application security testing(DAST)
通过模拟外部攻击来分析正在运行的应用以识别漏洞。它像真实用户那样与应用交互,以在无需访问源代码的情况下检测注入缺陷、认证问题与配置错误。AI 增强的 DAST 工具会基于应用行为而非固定模式生成测试用例,并尝试自动验证其发现,以解决误报问题。 -
Infrastructure-as-Code(IaC)扫描
在部署前分析 IaC 文件,以识别安全漏洞、配置错误与合规性问题。
这些类型的扫描器会在软件开发流水线的早期集成,符合左移方法。密钥扫描是一种推荐的安全实践,它会自动在代码仓库与其他数据源中识别并告警敏感信息,从源头上防止敏感信息被纳入代码库。SCA 工具通常也在流水线早期集成,在代码提交之后、构建之前运行。SAST 扫描可以作为构建阶段的一部分。容器扫描通常在构建出容器镜像之后、部署之前进行。
通过在开发流水线中贯穿引入 SCA、SAST、容器扫描、密钥扫描、DAST 与 IaC 扫描,你可以有效实施左移安全,主动保护应用免受漏洞影响。
你的测试工具识别出的每一个问题都必须进行分流与处置(triage)。需要付出成本去审查问题、判断其是否真实存在,并进行修复。误报(报告了但并不真实的问题)是一个严重问题:它们浪费审查者的时间,从其他安全工作与创新中抽走资源。更进一步,反复“喊狼来了”(crying wolf)会降低工程师对安全发现的信任,从而拖慢他们对其他真实问题的响应速度。因此,许多扫描工具利用 AI 的一个关键优先事项,就是减少误报数量。
分流难题还会因扫描器数量而加剧:不同工具可能以不同方式找到相同问题。在一些组织中,甚至会在同一代码库上同时使用多款 SAST 工具。在这种环境下,可以使用安全测试编排层,对发现结果进行去重与规范化,汇总为一份可管理的清单。在 AI-native(AI 原生)环境中,AI/ML 也可以在模式匹配与减少开发者繁琐劳动(toil)方面发挥作用。
在以上各类扫描中发现的问题都需要修复。为了简化开发者的流程,安全工具正日益通过专用的 AI 编码助手提供自动或半自动的修复功能。
保障软件供应链安全
在本节中,我们将考察当今软件供应链中固有的常见安全风险。我们会关注与代码仓库、CI/CD 流水线、制品仓库、开源依赖,以及支撑你软件开发流程的基础设施相关的风险。AI 正在改变组织发现并响应这些风险的方式——通过在复杂的供应链中识别出人力难以规模化监控的模式与异常。我们还将了解一系列可用于评估工具链安全性的框架与基准。读完本节,你将更好地理解潜在威胁及其缓解方法。
现代软件供应链的复杂性,使其成为人工智能的理想用例。AI 系统可以在代码库、构建系统与部署之间进行持续监控,以发现可疑模式。例如,ML 模型能够检测异常的提交模式(可能表明开发者账户被攻陷)、识别可疑的软件包行为(提示潜在的供应链攻击),或发现可能造成安全漏洞的配置漂移。这些 AI 能力为相互连接的组件提供了前所未有的可见性与防护。
识别最重要的 CI/CD 安全风险
专注于提升软件安全的领先组织 OWASP(Open Worldwide Application Security Project)给出了前 10 大 CI/CD 安全风险。如下所示,这些威胁类型多样。理解这些风险并落实推荐的缓解策略,有助于你加固 CI/CD 生态:
- Insufficient flow control mechanisms(流转控制机制不足)
当攻击者获得对流水线的访问权时,可能利用不足的流转控制绕过必要的评审与批准,将恶意代码或制品推入流水线,甚至进入生产环境,带来严重后果。 - Inadequate identity and access management(身份与访问管理不足)
多系统中海量身份的复杂管理与过度宽松的账户权限,容易导致失陷。一旦任一用户账户被攻陷,攻击者可能获得广泛访问,甚至触达生产环境。 - Dependency chain abuse(依赖链滥用)
利用开发/构建系统获取依赖的方式中的薄弱点,诱导其抓取并执行恶意包而非合法包。常见手法包括依赖混淆(用与内部包同名的恶意包)、维护者账号劫持(依赖劫持)、以及基于拼写错误的投毒(typosquatting)。 - Poisoned pipeline execution(流水线执行投毒)
通过被攻陷的源码管理系统向 CI/CD 流水线注入恶意代码。被投毒的代码在流水线内执行,可获得与构建任务等同的访问与权限,进而篡改构建配置、窃取凭据、外传数据或部署恶意制品。 - Insufficient pipeline-based access controls(基于流水线的访问控制不足)
当流水线执行节点对资源与系统拥有过高权限时,攻击者可在流水线内运行恶意代码,并滥用这些权限在 CI/CD 系统内外横向移动。 - Insufficient credential hygiene(凭据卫生不足)
广泛使用凭据且跨系统、跨场景的环境尤其高风险。示例包括:误把凭据推入代码库、在构建与部署流程中不安全地使用凭据、长期不轮换、在控制台输出或容器镜像中泄露等。 - Insecure system configuration(系统配置不安全)
典型工具链中系统与厂商众多,误配常见,如软件过期、过度宽松的访问控制或不安全的默认设置。攻击者可据此获得未授权访问、操纵 CI/CD 流程,甚至攻陷生产环境。 - Ungoverned usage of third-party services(第三方服务使用缺乏治理)
CI/CD 中的第三方服务虽便捷,却容易被授予对敏感资源的过度访问,从而扩大全组织的攻击面。缺乏治理与可见性导致难以维持恰当的访问控制,一旦第三方受损即带来风险。 - Improper artifact integrity validation(制品完整性校验不当)
交付涉及多阶段与多来源,恶意行为者可能在不触发告警的情况下篡改制品。若未被发现,受污染的制品会一路进入生产,执行恶意代码并危及系统。 - Insufficient logging and visibility(日志与可见性不足)
没有健全日志,你几乎对开发流水线中的恶意活动一无所知,难以及时发现并响应攻击。
理解这些风险并实施相应缓解策略,是构建安全、具备韧性的 CI/CD 生态的关键。
识别最重要的 OSS 风险
OSS 依赖的使用无处不在,组织必须应对其带来的安全与合规风险。前文提到两个案例:一是 Log4j 威胁,影响数以千计的系统;二是 XZ Utils 案例,虽被早期发现,但展示了恶意行为者攻陷 OSS 组件后可能造成的巨大破坏。
“通用漏洞与披露”(CVE)是组织用来识别已知安全问题并采取缓解措施的一种机制。CVE 监测工具会自动扫描你的软件并对潜在风险发出警报。尽管勤勉的监测有助于你消除所用 OSS 中的已知威胁,但这并不保证 OSS 组件真正安全。无人维护的组件或过时依赖同样带来风险,而 OSS 包往往还会引入数十个传递性依赖,使得管理异常复杂。
除 CVE 管理可对抗的已知威胁外,还存在其他类别的威胁需要应对。OWASP 基金会给出了如下 开源软件风险前 10 项,以更全面地刻画组织需要防范的 OSS 风险:
- Known vulnerabilities(已知漏洞)
开源组件可能包含已公开的安全缺陷(常通过 CVE 或其他渠道)。若可在你的软件中被利用,可能危及系统的机密性、完整性或可用性。 - Compromise of legitimate package(合法包被攻陷)
攻击者通过劫持账号或利用漏洞,向现有项目或分发基础设施注入恶意代码,导致终端用户或组织系统上执行恶意代码,危及机密性、完整性与可用性。 - Name confusion attacks(名称混淆攻击)
恶意行为者创建名称与合法组件极为相似的组件,诱使用户安装,从而在用户或组织系统上执行有害代码。 - Unmaintained software(无人维护的软件)
无人维护的 OSS 组件不再积极开发/支持,新漏洞可能没有补丁。下游开发者不得不自制补丁,增加工作量并拉长处置时间。 - Outdated software(过时软件)
在项目中使用过时组件会带来重大挑战:一旦当前版本曝出漏洞,紧急更新会变得困难;旧版本在安全性方面的测试也可能不如新版本充分。 - Untracked dependencies(未跟踪的依赖)
未被跟踪的依赖会在开发者不知情的情况下引入漏洞。出现原因包括 SBOM 不完整、SCA 工具能力有限,或通过手工方式安装。 - License risk(许可风险)
开源组件所用许可可能与预期用途不兼容、违反法律要求,或根本没有许可。使用无许可的组件或未遵守许可条款,可能导致法律后果。 - Immature software(不成熟的软件)
缺乏版本规范、测试或文档等最佳实践的不成熟开源项目,会为你的软件引入运营风险,导致不可预期行为、更多开发开销以及漏洞。 - Unapproved change(未批准的变更)
对软件组件进行未批准的更改,会破坏构建的完整性与可重现性。 - Under-/oversized dependency(依赖尺度不当)
开源组件在体量与功能上差异巨大,均可引入安全风险。小型组件虽功能有限,但因依赖上游项目仍可能带来显著风险;大型组件功能多,但因未使用的能力与依赖而拥有更大的攻击面。
在下一节中,我们将介绍一个可帮助应对这些风险的框架——SLSA。
确保软件制品供应链级别(SLSA)下的完整性
显然,开源软件(OSS)的风险是多方面的。在将 OSS 或任何第三方组件引入自家软件之前,我们必须问:这段软件是谁写的?它是否在我们信任的工具与平台上构建并发布?它携带了哪些依赖?它是否符合我们所重视的监管要求?
“Supply Chain Levels for Software Artifacts(SLSA,读作“salsa”)”是一个为回答这些问题而提供结构化方法的框架。SLSA 旨在在整个软件供应链中强化软件制品的完整性。它提升软件供应链的安全,并有助于应对我们前文提到的 OSS 威胁。
与实体证据的“监护链”(chain of custody)类似,SLSA 强调在软件制品整个生命周期中跟踪并验证其完整性的重要性。本节将深入介绍 SLSA,并给出如何遵循其要求以保护你的软件免受潜在威胁的指导。
SLSA 概览
SLSA 是一个由开放源代码安全基金会(Open Source Security Foundation)推动的开源项目。由于其聚焦于可落地实施与可度量的安全改进,SLSA 已获得广泛关注。
SLSA 为 OSS 与供应商软件的提供方和使用方都带来好处。在你的组织内部,你可以使用 SLSA 来帮助保护软件开发过程免受内部篡改。这可确保你部署到生产环境的代码,确实是你已构建、测试并签署通过的那份代码。
对于软件使用方,SLSA 提供了验证 OSS 真实性与完整性的机制。软件包注册表可以借助 SLSA 来保证上传的 OSS 软件包确实是从合法仓库中的源码构建而来。作为 OSS 使用者,从受信任的注册表获取软件包,能确保你下载的软件包是有效的。此外,你可以要求你的供应商遵循 SLSA 原则,并核验由可信第三方审计机构出具的供应商 SLSA 认证,以增添一层信任。
SLSA 定义了分级框架,允许组织逐步提升其软件供应链安全。级别代表防篡改的保证与防护程度的不断提高。未采取任何防护的组织视为 0 级。
SLSA Level 1 是基础。Level 1 要求生成基本的“来源(provenance)”信息。该信息应详述构建流程、描述依赖,并给出源代码位置。Level 1 是组织开启其软件供应链安全旅程的起点。使用方可据此评估采用该软件的风险。
Level 2 在 Level 1 的基础上引入更强的构建要求:你的构建环境必须隔离且受控。本级别还要求对制品进行签名以进行完整性校验,防止篡改。
最后,Level 3 要求源代码溯源与构建可复现。必须能够审计溯源信息,并确保其完整性。
表 5-1 总结了 SLSA 1.0 定义的三个级别在各项要求上的规定。
表 5-1. SLSA 等级
| Implementer(实施方) | Requirement(要求) | Degree(程度) | L1 | L2 | L3 |
|---|---|---|---|---|---|
| Producer(生产者) | 选择合适的构建平台 | ✓ | ✓ | ✓ | |
| Producer(生产者) | 遵循一致的构建流程 | ✓ | ✓ | ✓ | |
| Producer(生产者) | 分发溯源信息(provenance) | ✓ | ✓ | ✓ | |
| Build platform(构建平台) | 溯源信息生成存在(provenance generation exists) | Exists | ✓ | ✓ | ✓ |
| Build platform(构建平台) | 溯源信息生成可保证为真实(authentic) | Authentic | ✓ | ✓ | |
| Build platform(构建平台) | 溯源信息生成不可伪造(unforgeable) | Unforgeable | ✓ | ||
| Isolation strength(隔离强度) | 托管(Hosted) | ✓ | ✓ | ||
| Isolation strength(隔离强度) | 隔离(Isolated) | ✓ |
使用 SLSA 来确保完整性
以下原则指导了 SLSA 框架的设计决策:
-
信任少量平台;聚焦制品
将信任扩展到少数核心平台(例如构建与打包工具),然后自动化验证这些平台产出的制品。例如,你的受信任构建平台会为其参与构建的每个制品生成并签署溯源证明(provenance attestation)。下游平台再用公钥验证该溯源,从而自动判断某个制品是否达到了相应的 SLSA 等级。 -
将软件追溯到源代码,而非个人
在最终软件制品与其原始源代码之间建立直接且可验证的关联。此做法不同于信任拥有软件包注册表写入权限的个人,而是信任代码本身的不可变与可分析特性。通过建立直接关联,组织可以显著降低恶意代码注入或未授权修改的风险。 -
优先采用“证明”(attestations),而非“推断”(inferences)
依赖关于制品来源的直接证据,而不是基于对中间构建系统或其他系统的认知去推断制品的可信度。SLSA 要求对制品溯源做出显式证明,这需要对制品构建过程给出具体的佐证。
在 SLSA 1.0 中,构建平台是确保制品完整性的核心。这里的构建平台指负责编译、打包并准备你的软件进行分发的系统。要达到更高的 SLSA 等级,强健的构建平台至关重要。你选择的系统应支持隔离构建:对每一次构建都创建全新的基础设施,构建完成后即予以删除。此外,系统应强制执行非特权的、容器化的持续集成步骤,且不使用卷挂载。这可防止访问溯源密钥信息,符合 SLSA 规范要求。借助加固的构建系统,你可以确保恶意行为者无法篡改你的构建。
除选择能保障制品完整性的构建平台之外,你的系统还应生成并分发证明(attestations) ——即经过数字签名的记录,用以表明你的软件满足所期望的 SLSA 构建等级。SLSA 溯源证明是加密签名,为软件制品的来源与构建过程提供可验证的证据。它们就像“数字护照”,用以确保制品的完整性与真实性。
以使用 CI/CD 流水线构建的容器镜像为例,其 SLSA 溯源证明可能包含以下信息:
- Builder(构建器)
用于构建镜像的 CI/CD 平台(例如 GitHub Actions、GitLab CI/CD) - Invocation(调用)
用于创建该镜像的具体构建配置或脚本 - Materials(材料)
构建过程中使用的源代码仓库、依赖与其他输入 - Subject(主体)
制品本身,以其唯一摘要(哈希)标识 - Signature(签名)
由受信任实体生成的加密签名,用于验证该证明的真实性与完整性
为验证 SLSA 溯源证明,组织可以使用诸如 SLSA Verifier Service 之类的工具。该服务会核验证明的真实性、用受信签名方的公钥校验签名,并确保该证明符合 SLSA 规范。
为实现最大程度的安全性,SLSA 建议由构建平台而不是个体开发者来生成溯源信息。若你的组织尚未使用构建平台,应考虑采用支持 SLSA 的平台。对于第三方平台,检查其兼容性并在需要时请求 SLSA 支持。若你维护自有构建平台,请添加 SLSA 溯源生成能力。
同样,软件包生态应当在软件包旁一并分发 SLSA 溯源,可将证明嵌入软件包内部,或作为独立的元数据文件提供。若你的组织使用第三方生态,请询问其对 SLSA 的支持并遵循其指引。若直接分发,请在你的软件包制品中包含 SLSA 溯源。
通过利用 SLSA 溯源证明,你的组织可以对软件制品的真实性与完整性建立信心,并降低供应链攻击的风险。
超越 SLSA 的供应链安全增强
尽管 SLSA 为构建完整性提供了出色的框架,但它主要聚焦于制品溯源与构建系统完整性。要应对 OWASP CI/CD 十大风险所涵盖的完整供应链风险范围,组织还需要额外的安全措施。
一套全面的供应链安全策略应包括:
持续的行为监测
由 AI 与 ML 驱动的现代交付与安全平台正在改进,可在代码库、构建系统与部署流水线中检测异常活动。这些系统会建立正常行为的基线,并标记可能表明遭到入侵的偏离。Datadog CI 和 GitGuardian 等监测与安全工具是当下的常见选择。
高级依赖分析
不仅限于基础的漏洞扫描,智能分析工具还能通过评估软件包行为、代码模式以及维护者活动趋势,在公开披露之前识别潜在的恶意依赖。借助 AI 的系统可以通过分析代码语义与行为来发现微妙的入侵指示器,这是传统扫描器无法做到的,有助于抵御依赖混淆或拼写劫持等复杂的供应链攻击。
自动化策略执行
在整条流水线中实施自动化的策略护栏,强制执行超越构建完整性的安全要求。这些系统可阻止过度宽松的访问、拦截危险配置、并确保正确的密钥管理——从而应对 SLSA 未能充分覆盖的 RBAC 不足与凭据卫生等风险。就当下而言,在交付平台上广泛落地策略仍不均衡。展望未来,这是一种强有力的做法,并将受益于 AI:既体现在对变化威胁的更强适应性上,也体现在通过 AI 协助在 PaC 场景中快速生成策略上。
供应链风险预测
预测性分析与 AI 模型会分析历史漏洞趋势与新兴威胁情报,突出指出供应链中潜在风险更高的组件,帮助团队在问题变得严重之前主动处置漏洞。通过对数千个项目与依赖的模式进行分析,这些系统能在引发安全事件之前识别你环境中的风险因素,从而对薄弱区域进行前置加固。
通过将这些 AI 增强能力与 SLSA 对构建完整性的关注相结合,组织可以形成一种纵深防御的方法,覆盖供应链风险的全谱系。这一综合策略不仅保护构建过程,也保护从开发到部署的整个软件交付流水线。
应对由 AI 生成的依赖风险
随着组织越来越多地采用 AI 编码助手,一种新的供应链风险出现了:AI 幻觉抢注。当攻击者注册 AI 工具因幻觉而错误建议的包名时,就会形成注入恶意代码的通道。
尽管核心的 SLSA 框架可对传统供应链攻击提供重要防护,但使用 AI 编码工具的组织应落实额外的保障措施:
经验证的注册表策略
将包管理器配置为只从官方审核过的注册表与包含“已知良好”包的私有仓库拉取。即便 AI 助手给出建议,也能防止开发者无意中从不受信来源安装软件包。
软件包年龄与流行度校验
实施工具,自动依据最低下载量与既有历史指标校验被推荐的软件包。对使用量极低的新包应触发额外审核。
AI 置信度核验
当使用会为其推荐提供置信度分数的 AI 编码助手时,建立流程,对低置信度的软件包建议进行人工复核,并以权威来源加以验证。
预安装验证
在开发环境中加入自动化检查,在允许将依赖写入项目文件之前,先在受信注册表中验证其存在性与溯源。
将这些附加控制与 SLSA 实践及完整的 SBOM 结合,可形成纵深防御,既防范传统的供应链攻击,也能抵御由 AI 促成的新兴威胁。通过针对 AI 在依赖选择过程中新引入的特定风险采取措施,组织就能在保持供应链完整性的同时,安全利用 AI 编码助手。除 AI 置信度核验外,以上每项做法对其他基于软件包的攻击(如拼写劫持)同样有益。
用软件物料清单(SBOM)应对零日漏洞
在第一节中,我们回顾了 Log4j 漏洞利用:攻击者通过利用日志消息中的特定模式即可远程执行任意代码,导致广泛的数据泄露、勒索软件攻击以及关键服务中断。它是零日漏洞利用的一个例子——这种威胁极为阴险,因为它利用的是软件供应商尚未知晓的漏洞,使攻击者在任何防御措施建立之前就占据显著优势。本节将说明 SBOM 如何成为对抗此类漏洞的关键工具。SBOM 为某个软件制品中使用的所有组件与依赖提供一份详细清单。我们将了解 SBOM 的组成与特性,以及它在整个 SDLC 中如何被管理。
虽然用于跟踪与管理软件组件的依赖管理工具与包管理器已存在多年,但自 2018 年以来,SBOM 取得了显著进展。包括 NTIA(美国国家电信与信息管理局)多方参与进程在内的协作努力,已为 SBOM 制定了最佳实践与建议。这一协作将业界专家、政府机构与学界汇聚在一起,共同定义了 SBOM 的生成、共享与使用的标准与指南。
因此,SBOM 已成为关键的基础构件。事实上,Linux 基金会的最新研究发现,2022 年有 78% 的组织在生产或使用 SBOM,比前一年增长了 66%。
为你的软件创建 SBOM 时有两项标准可选:
-
CycloneDX
CycloneDX 项目已成为 SBOM 的领先标准之一,提供了一种机器可读的格式来表示软件组件、依赖及其关系。CycloneDX 获得了各方广泛采用与支持。 -
SPDX
Software Package Data Exchange(SPDX)是另一项流行的 SBOM 标准,由 Linux 基金会赞助,并被编入国际标准 ISO/IEC 5962。它提供了灵活且可扩展的组件表示格式。SPDX 多年来在开源社区被广泛使用。
SPDX 更为成熟,覆盖范围更广,不仅包含组件信息,还包含关于 SBOM 本身的元数据(如创建者与创建日期)。它特别适合管理开源许可证并共享有关软件包的信息。
CycloneDX 较新,提供更结构化、机器可读性更强的描述,重点在于提供关于软件组件及其关系的详细信息。由于灵活与易于适配,CycloneDX 常被用于更广泛的用例。采用哪一标准取决于你的具体场景;你为软件供应链安全管理选择的工具与流程应能同时支持这两种标准。
无论选择何种格式,评估 SBOM 质量的因素是相同的。NTIA 制定了一组 SBOM 的最小要素,用于提供关于软件组件及其依赖的关键信息。确保包含这些要素,有助于在各种工具与平台上对 SBOM 进行有效分析,并遵循底层的 SPDX 或 CycloneDX 规范。
通过提供完整的组件清单,SBOM 带来透明性与可追溯性,有助于确保符合组织的安全策略与法律要求。PaC(Policy as Code,策略即代码)框架可以利用 SBOM 实现合规的自动化。使用 PaC,你以代码定义安全策略,并可像代码一样进行管理与版本控制。随后这些策略可应用于 SBOM,确保软件组件遵循组织对开源软件的安全标准。自动化的合规能降低人为错误风险并提升效率。
例如,你的组织可以定义一项策略,只允许使用宽松许可证(如 MIT、Apache License 2.0)的开源组件,以确保与现有软件组合的兼容,并避免潜在法律问题。
你也可以定义策略,自动拒绝超过某一严重性阈值的已知漏洞的开源组件。或者,建立评估开源供应商声誉与可信度的标准,包括供应商规模、安全实践与社区参与等因素。
将 SBOM 与 PaC 结合,能形成一套强有力的开源使用治理框架,确保合规并降低安全风险。对安全策略的自动化执行能减轻安全团队负担并提升整体效率。
使用 SBOM 修复依赖问题
在依赖繁多的复杂代码库中,定位并修复受影响的制品可能相当艰巨。遵循以下最佳实践有助于你的组织能够快速应对零日漏洞与其他威胁:
保持 SBOM 最新
确保在 CI/CD 流程中自动生成 SBOM。这样,你就始终掌握组织所支持的每个制品的依赖信息。
-
使用自动化漏洞扫描工具
使用自动化工具将 SBOM 与漏洞数据库进行比对扫描。这些工具能及时识别依赖中的已知漏洞,帮助你确定修复优先级并处理潜在安全威胁。 -
建立稳健的补丁管理流程
制定明确定义的流程来修补在 SBOM 中识别出的漏洞,包括设定修补优先级、与供应商协调,以及在部署前测试补丁。通过保持软件供应链的最新与安全,可显著降低零日漏洞被利用的风险。
AI 大幅强化了这些最佳实践。智能 SBOM 分析系统可以:
-
预测漏洞影响
AI 模型可分析你的应用架构,判断某个存在漏洞的组件是否处于可被利用的位置,从而区分“理论上的漏洞”与“立即构成风险的漏洞”。该情境化分析有助于团队优先处理最关键的问题。 -
自动化依赖更新
当识别到漏洞时,AI 系统可自动生成包含合适依赖更新的拉取请求,测试其与代码库的兼容性,并在多个代码仓库间管理更新流程。这种自动化大幅缩短从漏洞披露到修复完成的时间。 -
识别隐藏依赖
ML 算法可以发现未记录或传递性的依赖,这些依赖可能未在包清单中明确列出,从而更完整地呈现你的实际攻击面。
采用 DevSecOps 原则
本章我们已经看到软件供应链有多么脆弱。要持续、可靠地以安全方式交付软件,仅仅对所用工具和第三方组件进行严格审查还不够;仅仅选择支持 SLSA、能生成 SBOM 与证明(attestations)的 CI/CD 工具与技术也不够。为了确保一致的安全交付,你的团队必须:维护一个安全的平台,进行彻底的漏洞测试,及时确定优先级并修复问题,阻止不安全代码发布,遵从监管要求,并保证你的软件及其所有组件的完整性。
这不可能是团队中某一个角色或组织内某一个团队单独完成的工作。它需要一种将安全整合进整个 SDLC 的协作式方法。这正是 DevSecOps 所强调的。与传统做法只在少数环节“加上”安全不同,DevSecOps 推动开发、安全、运维团队持续协作,确保从一开始就考虑安全。
本节将解释 DevSecOps 原则,并说明采用这些原则如何帮助你更快识别与修复漏洞、降低泄露风险、提升软件的整体安全性。
建立协作文化并打破职能孤岛
成功实施 DevSecOps 的第一步、也是最关键的一步,是建立以安全为先的协作文化。显然,这往往是最难的一步,需要组织领导层的全力支持。安全必须成为组织级优先事项,并成为开发、运维、安全团队及其他相关方的共同责任。
打破孤岛、建立共同所有感的一个简单方法,是创建跨职能的 DevSecOps 团队。被孤立的团队会限制沟通与知识共享,导致重复劳动与流程不一致。相比之下,跨职能 DevSecOps 团队有助于协作与开放沟通。比如在制定一项新的安全实践或选型新的安全相关工具时,纳入开发、运维与安全角色的视角,更容易获得成功所需的认同与一致。
此外,跨职能团队还能避免做出造成瓶颈、影响生产力的选择或建议。比如单方面强制加入某些新的应用安全检查,而不考虑它们对开发流程的影响。这样的结果是开发者工作量增加,既影响产出,也伤害组织内部的信任与合作氛围。
除组建跨职能团队外,你还应在组织内识别并支持若干关键的“安全倡导者(security champions)”,以推动安全举措、提升同侪的安全意识。利用跨职能团队与安全倡导者,通过建立开放透明的沟通渠道来分享想法、传达进展,促进信息与观点的交换。这些渠道可以包括定期会议、团队聊天、知识分享会等。
AI 工具可作为安全与开发团队之间的协作桥梁,提供共享上下文,并在安全与开发关注点之间进行“翻译”。例如,当一款由 AI 驱动的安全工具发现漏洞时,它既能用开发者易于理解的方式解释问题,也能提供安全团队所需的安全背景。这种共享理解可减少团队间的摩擦,帮助建立“人人讲同一种语言”的安全文化。
最后,投入于安全培训。识别技能差距,为所有团队成员提供持续的安全培训,使其具备识别与缓解安全风险的知识与技能。这不仅提升整个团队的能力,也体现了组织将安全置于优先位置的承诺。
采纳并执行安全编码方法论并左移
安全编码实践对防止漏洞至关重要。OWASP Top 10 和 CWE(Common Weakness Enumeration)为识别与处理常见安全漏洞提供了有用的指导。此外,请确保你的方法论覆盖以下常见威胁:
- 输入验证
始终验证用户输入,防止恶意数据被注入应用。这有助于防止 SQL 注入、XSS 等注入攻击。 - 输出编码
正确地对输出进行编码以防止 XSS。确保用户生成内容被安全地展示,而不会允许恶意代码执行。 - 错误处理
实施健壮的错误处理,防止信息泄露与潜在漏洞。避免显示可能为攻击者提供有价值信息的敏感错误消息。 - 会话管理
采用安全的会话管理技术以保护用户数据并阻止未授权访问,包括使用强健的会话标识并实现会话超时。 - 认证与授权
实施强认证机制,并执行恰当的授权控制以限制对敏感资源的访问。 - 加密
使用安全的密码学算法与实践来保护敏感数据。避免弱加密方法,并确保正确的密钥管理。 - 依赖管理
及时更新并以安全方式管理依赖,避免漏洞。使用依赖扫描工具识别并处理第三方库中的已知漏洞。
即便持续了解最新威胁并遵循安全编码,组织的最佳努力也难以做到万无一失。静态与动态分析工具,加上早期阶段的安全测试,能作为“兜底”,捕捉代码评审中可能被忽略的问题。这正是“左移”的意义所在。我们已经介绍过左移如何使你在早期就识别与处理漏洞。尽早修复可降低漏洞进入生产代码的风险。
总结
在现代软件开发中,安全不能是事后考虑,而必须贯穿整个开发过程。正如本章所示,AI 原生的安全方法变革了:
- 漏洞的发现方式:依靠智能分析,而非仅靠静态规则
- 发现结果的优先级:基于实际风险,而非通用严重性分级
- 修复的实施方式:通过自动化指引与代码生成
- 供应链的防护方式:通过持续监控与异常检测
- 团队的协作方式:在安全与开发之间建立共享的上下文与理解
通过将安全嵌入从设计到部署的每一个阶段,并培育一种由 AI 赋能的共同责任文化,组织就能构建与交付能够抵御现代威胁的应用。
在第 6 章,我们将把注意力转向利用混沌测试(chaos testing)来提升应用韧性,从而发现那些否则可能被忽视的薄弱点。