人工智能如何改变补丁更新流程,以及开发人员需要了解哪些关于漏洞暴露管理的相关知识
当漏洞扫描工具报告你的应用程序存在23个安全漏洞时,其中4个属于严重等级,7个为较高风险等级,剩下的12个则为中等风险等级,乍一看,解决办法似乎很明确:立即开始修补这些漏洞。但究竟应该先修复哪一个呢? 这在漏洞管理中一直是个棘手的问题。虽然安全团队可能会及时发现存在漏洞的代码依赖项,但并不总能立刻对其进行修复。开发人员需要确保这些有漏洞的代码仍在被使用中,并在将修复方案部署到生产环境之前完成所有必要的测试。 不过,最近在利用人工智能来检测软件漏洞及攻击手段方面确实取得了一些显著的进展。例如,这篇 研究 就详细介绍了相关的研究成果以及未来的发展方向。 但这一切究竟如何才能真正帮助开发社区呢?我们
当漏洞扫描工具报告你的应用程序存在23个安全漏洞时,其中4个属于严重等级,7个为较高风险等级,剩下的12个则为中等风险等级,乍一看,解决办法似乎很明确:立即开始修补这些漏洞。但究竟应该先修复哪一个呢?
这在漏洞管理中一直是个棘手的问题。虽然安全团队可能会及时发现存在漏洞的代码依赖项,但并不总能立刻对其进行修复。开发人员需要确保这些有漏洞的代码仍在被使用中,并在将修复方案部署到生产环境之前完成所有必要的测试。
不过,最近在利用人工智能来检测软件漏洞及攻击手段方面确实取得了一些显著的进展。例如,这篇研究就详细介绍了相关的研究成果以及未来的发展方向。
但这一切究竟如何才能真正帮助开发社区呢?我们确实需要更快地修复漏洞,但更重要的是,我们必须能够判断出哪些漏洞才是真正值得优先处理的。
在本文中,我们将探讨传统的漏洞修补流程是怎样的,人工智能是如何缩短安全团队响应时间 的,以及为什么仅仅根据漏洞的严重程度来决定修复顺序并不总是合理的。
我们还会讨论暴露管理这一概念,以及它与传统漏洞管理方法之间的区别。随后,我们会介绍开发人员如何通过分析代码依赖关系、代码的可访问性以及软件成分清单来确定应用程序中存在的实际安全漏洞。
本文涵盖的内容:
打补丁与风险暴露管理:两者有何区别?
在探讨人工智能如何改变漏洞应对方式之前,了解两个重要概念是很有帮助的:打补丁和风险暴露管理。
什么是打补丁?
打补丁是指通过更新软件来修复现有问题,这些问题可能包括安全漏洞、程序错误或稳定性问题。具体操作可能是升级存在漏洞的库文件,为操作系统应用安全补丁,或者使用已修复漏洞的新版本应用程序。
例如,如果你的应用程序使用了某个存在安全漏洞的库文件,那么在该库的补丁版本发布后,你就应该立即进行升级。之后还需要测试这个更新,确保应用程序仍能正常运行,然后再将升级后的版本部署到生产环境中。
因此,打补丁并不仅仅是安装最新版本的软件包而已。某些依赖关系的更新可能会破坏应用程序的API、某些功能,甚至影响其他相关软件包的正常运行。正因如此,团队在发现漏洞、决定是否进行更新、进行测试、部署更新以及验证更新效果时,通常会采用一套完善的风险管理策略。
什么是风险暴露管理?
虽然漏洞管理的主要目标是识别漏洞,但风险暴露管理的关注点则更为广泛——它着重于判断这些漏洞是否真的会成为攻击者实施攻击的途径。
例如,一个仅在开发系统中使用的有漏洞的库文件,所构成的威胁通常比那些被用于能够访问数据库的公开系统中的类似漏洞库文件要小得多。
在评估风险时,需要考虑的因素包括网络可访问性、资产暴露情况、存在漏洞的代码路径、身份认证与访问控制机制、云环境,以及系统和数据的敏感程度等。
简而言之,漏洞管理侧重于发现和追踪漏洞,而风险暴露管理则旨在判断哪些漏洞真正构成了严重的安全威胁。
传统的补丁管理流程是按照时间顺序来设计的
传统的漏洞应对流程是一步一步依次执行的。
发现漏洞
安全团队评估漏洞的严重性
维护人员发布补丁文件
开发人员更新相关依赖库
持续集成/持续交付流程执行回归测试
将补丁部署到生产环境
验证修复效果
这种流程本身并没有什么缺陷,但它基于一个隐含的前提:防御者有足够的时间来完成每一个步骤。
让我们以一个依赖性漏洞为例来进行实践。如果自动化扫描工具在像lodash这样的常用工具包中检测到了漏洞,工程师们并不会立即在生产环境中更新相关依赖版本的代码。他们需要先确认应用程序代码是否确实使用了存在漏洞的函数,检查升级后是否存在会导致系统故障的API变更,并通过集成测试来验证修改后的代码是否能正常运行。
每项安全补丁本质上都是对代码的修改,因此必须确保这些修改能够安全地经过开发与部署流程。
人工智能正在缩短“发现漏洞”到“被利用”之间的时间间隔
过去存在于漏洞被发现与被实际利用之间的时间差正在逐渐消失。这是因为自动化程序能够扫描代码库,生成概念验证结果,并识别出一些边缘情况。
现代的人工智能系统能够帮助研究人员以及潜在的攻击者完成诸如静态二进制分析、漏洞检测、制作攻击载荷,以及在复杂的软件设计中找出逻辑错误等任务。
像DARPA的人工智能网络安全挑战赛这样的项目就展示了如何利用人工智能系统来自动发现并修复复杂开源软件中的漏洞。在2024年的半决赛中,自主运行的网络安全系统针对基于Jenkins、Linux内核、Nginx、SQLite3和Apache Tika等实际软件开发的项目进行了测试。这些系统共发现了22个虚构的漏洞,并成功修复了其中15个;同时它们还发现了一个存在于SQLite3中的真实漏洞,并负责任地将这一信息公之于众。
在实际的开发过程中,补丁制作过程中的某些任务完全可以由人工智能来完成。人工智能可以执行代码分析和依赖关系分析,从而帮助检测潜在的漏洞;它还能协助追踪那些使用了存在漏洞的函数的代码段,提出修改代码或依赖关系的建议,并生成测试用例来确保所推荐的补丁不会破坏现有系统的功能。安全团队也可以利用人工智能来进行模式识别。
随着人工智能工具在评估软件和检测漏洞方面的能力不断提高,从发现漏洞到采取补救措施之间的时间间隔正在变得越来越短,这一变化也极大地影响了安全专业人员处理人工智能与漏洞管理问题的方式。尤其是当漏洞被利用的时间窗口越来越短时,对漏洞的优先级进行合理划分就显得尤为重要。
人工智能还可以通过将漏洞信息与运行这些存在漏洞的软件所处的环境联系起来,来辅助进行漏洞管理。例如,一个由人工智能辅助运行的安全系统可以将某个有漏洞的依赖项与那些面向互联网的应用程序、它们的网络连接配置、云服务权限以及它们能够访问的数据或服务关联起来。这样,安全团队就能从单纯地判断是否存在漏洞,转变为思考攻击者通过这些漏洞实际上能够达到什么目的。
为何“修补所有漏洞”在大规模环境中行不通
当一个组织范围内的扫描工具检测出分布在多个微服务中的500个漏洞时,立即针对每一个漏洞采取行动显然是不可能的。开发人员很容易就会因收到过多的警报而感到疲惫不堪。
常见漏洞评分系统(CVSS)是一种用于描述漏洞严重程度的标准化框架。CVSS v3.1将漏洞的严重程度分为以下几类:
CVSS评分 | 严重程度 |
0.0 | 无危险 |
0.1–3.9 | 低风险 |
4.0–6.9 | 中等风险 |
7.0–8.9 | 高风险 |
9.0–10.0 | 极高风险 |
CVSS之所以有用,是因为它为开发人员和安全团队提供了一种共同的语言,用来描述漏洞的严重程度。然而,这个评分系统仅仅描述了漏洞本身,并没有说明该漏洞出现在什么样的环境中。换句话说,CVSS无法告诉你:应用程序是否真的会使用那些受到漏洞影响的功能,或者受影响的系统是否暴露在互联网上。
为了了解为什么仅依靠CVSS并不总能解决问题,我们来看两个假设性的例子:
漏洞A:这是一个极其危险的远程代码执行漏洞,但它存在于一个独立的测试环境或仅供开发使用的依赖库中,从未被部署到生产环境中,也没有任何外部网络访问权限。
漏洞B:这是一个高风险的输入验证漏洞,存在于一个面向互联网的API网关中。该网关会处理用户的恶意输入,并且能够访问存储客户信息的后端数据库。
如果只看CVSS评分,团队可能会优先处理漏洞A而不是漏洞B。但显然,漏洞B对系统的运行构成的威胁要大得多。安全研究表明,一旦某种漏洞被发现,实际上只有极少数会被真正利用。来自CISA KEV目录的监测数据也清楚地显示,攻击者通常会针对那些确实存在被利用可能性的漏洞进行攻击。
在实际操作中,团队在决定哪些漏洞需要修复时,除了要考虑CVSS评分之外,还必须综合考虑许多其他因素。如果满足以下条件,某个漏洞可能会被赋予更高的优先级:
该漏洞会影响一个面向互联网的生产系统;
已经存在针对该漏洞的攻击手段;
该漏洞会导致敏感信息泄露;
该漏洞会影响到企业的关键业务流程;
或者该漏洞能为攻击者提供入侵其他受权限保护的系统的途径。
但是,那些仅在开发阶段出现或由于某些原因无法被访问的漏洞,很可能并不需要立即得到修复。
确定漏洞重要性的最恰当方法就是提出一些简单直接的问题:受影响的系统是否可被访问?存在问题的代码是否可被访问?针对这一漏洞是否存在任何利用手段?受影响的服务拥有哪些权限?攻击者在利用该漏洞后能够获取哪些信息或资源?
如果对所有警报都赋予相同的优先级,那么工程资源就会被浪费在那些实际上并不会带来任何风险或仅带来极小风险的漏洞上。
暴露管理:从单纯统计漏洞数量转向评估实际风险
暴露管理的重点已经从仅仅记录静态漏洞,转变为评估组织实际面临的安全风险状况。
与其问“我们的代码库中存在多少个CVE漏洞?”,不如问“哪些存在问题的组件、配置错误或可被访问的网络路径会给我们正在运行的系统带来安全风险?”
当你了解这两种方法各自关注的重点时,这种区别就会变得更加明显:
评估维度 | 传统的漏洞管理方法 | 暴露管理方法 |
主要关注点 | 存在哪些软件缺陷和CVE漏洞? | |
数据范围 | ||
当一个工程环境需要管理10,000个云资源,而通过依赖关系扫描工具发现了1,000个存在问题的库文件时,这些数字并不能真实反映实际的安全状况。为了准确判断风险级别,就必须了解这些漏洞所处的具体环境背景。
该容器是否直接暴露在互联网上,还是被内部负载均衡器保护着?
代码中是否真的调用了那些存在风险的函数或库文件?
通过这个有问题的服务,能够访问哪些身份权限、云角色以及数据库资源?
了解这一分母(即应接受特定补丁的资产总数)有助于团队识别那些真正构成威胁的安全漏洞,从而将开发资源集中在解决那些会影响生产数据的问题上。
依赖关系树作为攻击面
现代软件交付过程依赖于多种层级的包,例如 npm、PyPI、Maven、NuGet、基础操作系统包、GitHub Actions以及第三方 API。应用程序的逻辑由开发人员编写,但最终的运行时软件实际上包含了众多层次的包:
你的应用程序逻辑 → 直接依赖关系(在配置文件中明确列出)→ 传递依赖关系(自动被引入项目)→ 底层操作系统包 → 基础容器镜像/云运行环境。
如果某个漏洞存在于三层以下的传递依赖关系中,且该传递依赖关系未得到维护,但可以通过外部输入被利用,那么这个漏洞就成为了你应用程序攻击面中的重要组成部分。
正因如此,软件开发团队开始使用软件成分清单(SBOM)。SBOM是一种记录构成软件或应用程序的所有组件的清单。根据生成 SBOM所使用的技术不同,其中可以包含不同的信息,比如组件名称、版本号、依赖关系以及包 ID 等。
当发现新的安全漏洞时,SBOM会起到很大的帮助作用。例如,如果在 lodash 的某个特定版本中发现了漏洞,安全团队就可以利用 SBOM 来确定哪些应用程序或容器镜像使用了受影响的版本,进而判断是否存在可被利用的安全风险。
单凭 SBOM本身并不能为应用程序提供足够的安全保障。它的意义在于让开发人员和安全人员更加清楚地了解自己所使用的应用程序中究竟包含了哪些组件。
对开发人员的实际建议
一旦将这些原则融入到团队的日常开发流程中,它们就会发挥出实际作用。你和你的团队可以通过以下一些具体方法来应用这些最佳实践和策略:
审核传递依赖关系
首先需要做的是确认应用程序中包含了哪些依赖关系。对于传递依赖关系来说,这一点尤为重要,因为这些依赖关系可能是由于在安装其他包时被自动添加进项目中的。
对于 Node.js 应用程序,可以使用 npm ls 命令来查看依赖关系树;Python 开发者可以使用 pipdeptree,而使用 Maven 编写的 Java 应用程序则可以通过 mvn dependency:tree 命令来获取依赖关系信息。这些命令能帮助你了解各种包的来源,以及是哪个直接依赖关系将有漏洞的传递依赖关系引入到了你的项目中。
检查代码的可访问性
在依赖关系中发现漏洞,并不意味着你的应用程序中一定使用了该依赖项。不要将每一份漏洞报告都视为会严重影响生产运行的问题。相反,你应该先查明受影响的功能是否真的能在你的应用程序中被使用。
假设你在某个库函数中发现了漏洞,这时你需要检查整个代码库中是否有使用该函数的地方,并判断是否存在将用户控制的数据传递给该函数的可能性。你可以使用集成开发环境提供的搜索功能,或者像grep这样的命令行工具来进行查找。
如果某个函数未被使用,或者从外部无法访问,那么这个漏洞的紧迫性就会降低。但这并不意味着可以忽略它。
在CI/CD流程中生成软件成分清单
你也可以利用CI/CD管道来生成软件成分清单。制作这样的清单有助于你了解软件中使用了哪些组件,从而在发现漏洞时更容易确定哪些组件受到了影响。
例如,使用Syft工具,你可以通过执行以下命令从容器镜像中生成软件成分清单:syft my-app:latest -o cyclonedx-json > sbom.json。
这样就会生成一个CycloneDX格式的JSON文件,其中包含了容器镜像中所包含的组件信息。这份清单会与构建生成的文件一起被保存起来。一旦某个特定版本包中出现了新的漏洞,安全团队就能很快知道哪些应用程序和容器镜像使用了这个有问题的组件。
在补丁尚未准备好时采取补偿性控制措施
有时可能还没有可用的补丁,或者立即应用补丁会带来风险,因为这样做可能会导致需要进一步测试的故障问题。在这种情况下,你可以采取补偿性控制措施,来降低应用程序受到攻击的风险,直到补丁正式发布。
根据具体的环境,这些措施可能包括限制对受影响组件的网络访问权限、将相关任务与敏感资源隔离开来、禁用被攻破的功能,或者降低应用程序的权限等级。
这些控制措施并不能替代安全补丁,但它们可以在补丁生效之前减少被利用的风险。
在运行时实施最小权限原则
最后,要限制应用程序在运行时的访问权限。这样,即使发生了安全漏洞,也能防止该漏洞扩散到其他应用程序或系统中。
在部署基于容器的应用程序时,你可以使用只读文件系统,同时移除Linux系统中不需要的功能。例如,Docker允许在运行容器时使用--read-only和选项来限制权限。
云应用程序也需要采用同样的理念,通过确保使用IAM权限来仅允许应用程序所需的功能被访问。
如果某个安全环节遭到破坏,攻击者应该只能获取环境中尽可能少的组件。
软件安全的未来并不取决于企业能够多快地更新他们的软件包,也不在于他们是否了解这样做的根本原因。随着漏洞检测技术通过自动化手段变得更加高效,有效的防护措施实际上依赖于对源代码、其依赖关系以及运行时基础设施之间相互关系的深入理解。
我们的目标不仅仅是发现新的漏洞,而是要识别那些真正会对应用程序构成威胁的漏洞。
总结
虽然人工智能帮助团队更快地发现漏洞,但现代应用程序却越来越依赖于众多不同的软件层。这并不意味着打补丁就变得没有必要了,只是意味着并非所有的漏洞都需要立即得到处理。
开发者仍然需要弄清楚这些漏洞存在于哪些地方、攻击者是否能够利用它们,以及它们可能会造成什么影响。由于从发现漏洞到被实际利用之间的时间间隔在不断变化,因此了解漏洞可能带来的风险与补丁本身一样重要。
相关文章
如何使用屏幕阅读器来使用 Discord:快速指南
Discord就是这样一种技术:几年前它突然出现,如今已经无处不在。 各种社区、项目和倡议都建立了大量的服务器,而且这类服务器还在不断涌现。在很大程度上,它们已经取代了论坛、聊天室,有时甚至也替代了文档网站和新闻板块的功能。 这种变化究竟是好是坏,还有待讨论,但可以肯定的是,Discord将会长期存在下去。 就可访问性而言,Discord曾经面临过一些问题。多年来,对于使用屏幕阅读器的用户来说,使用这款软件一直非常不便,因为开发者显然没有充分考虑过可访问性的需求。 不过在过去的几年里,这种情况已经得到了显著改善。虽然到2026年时,Discord仍然不是完全适合所有用户使用的工具,但只要掌握了
阅读全文
如何使用Node.js、Express和MongoDB构建一个用于奖学金申请研究的MCP服务器
寻找奖学金信息其实是一项需要系统地进行研究的任务,而不仅仅是通过简单的搜索来完成的。你需要根据学科领域、平均成绩、国籍以及截止日期等条件来筛选各类奖学金信息,然后列出候选名单,并对相关申请材料及推荐人的意见做好记录。一周后,你再回顾这些信息,尝试回忆自己当初为什么选择保存某个具体的奖学金项目。 人工智能助手可以帮助完成这一工作流程,但前提是它必须能够访问真实的数据库,并能保留你之前所做的筛选和决策结果。聊天记录并不能替代数据库;而那些被错误设定的截止日期反而会比根本没有截止日期更糟糕。 Model Context Protocol (MCP) 为人工智能应用程序提供了获取这类信息的标准接口。在
阅读全文
使用OpenTelemetry实现Claude Code的可观测性
像 Claude Code 、 OpenAI Codex 、 Google Antigravity 以及 Cursor 这样的代理编码工具,在日常软件开发中已经变得无处不在。 随着代理系统的不断发展,开发者让这些系统完成的大部分工作都是通过逐个分配子任务来实现的。许多团队也在探索并使用共享的、多租户式的代理基础设施,这种架构的成本不会与某个特定的所有者挂钩。在这种情况下,可观测性就成为了监控基础设施成本的关键因素。 在本指南中,您将了解可观测性的工作原理,然后学习如何启用Claude Code内置的遥测功能,运行后端程序来收集数据,并读取该系统生成的各类指标、日志及追踪信息。这些内容将帮助您更
阅读全文
jQuery的发展历程:这个小小的库是如何彻底改变网页开发领域的?
jQuery由John Resig创建,于2006年正式发布。它是一个JavaScript库,能够简化HTML操作、事件处理、动画效果以及Ajax功能的实现。由于提供了跨浏览器的通用API,jQuery极大地便利了网页开发工作。尽管随着现代框架的兴起,其使用频率有所下降,但如今仍有大量网站在使用jQuery。 作者:Daniel Curtis
阅读全文