易受攻击的依赖管理备忘录¶
简介¶
本备忘录的目标是针对检测到易受攻击的第三方依赖项时如何处理提供一种方法建议,具体取决于不同的情况。
本备忘录并非以工具为导向,但它包含一个“工具”部分,旨在向读者介绍可用于检测易受攻击依赖项的免费和商业解决方案,具体取决于对现有技术的支持程度
注意
本备忘录中提到的建议并非万能(适用于所有情况的解决方案),但可作为基础并根据您的具体情况进行调整。
背景¶
大多数项目使用第三方依赖项来委托处理各种操作,例如生成特定格式的文档、HTTP 通信、解析特定格式的数据等。
这是一种很好的方法,因为它允许开发团队专注于支持预期业务功能的实际应用程序代码。然而,这种依赖性也带来了一个预期的负面影响,即实际应用程序的安全态势现在依赖于它。
这一点在以下项目中有所提及
- OWASP TOP 10 2017,在点 A9 - 使用含有已知漏洞的组件 下。
- OWASP 应用程序安全验证标准项目,在部分 V14.2 依赖项 下。
基于此背景,项目必须确保所有实现的第三方依赖项都没有任何安全问题,如果它们确实包含任何安全问题,开发团队需要了解并采取必要的缓解措施来保护受影响的应用程序。
强烈建议从项目启动之初就对依赖项进行自动化分析。事实上,如果这项任务在项目中期或后期才添加,可能意味着需要大量工作来处理所有识别出的问题,这反过来会给开发团队带来巨大负担,并可能阻碍当前项目的进展。
注意
在本备忘录的其余部分,当我们提到“开发团队”时,我们假设该团队包含一名具备所需应用程序安全技能的成员,或者可以咨询公司中拥有此类技能的人员来分析影响依赖项的漏洞。
关于检测的说明¶
重要的是要记住安全问题在发现后有不同的处理方式。
1. 负责任披露¶
在此查看说明。
研究人员在一个组件中发现漏洞,在与组件提供商合作后,他们发布一个与该问题相关的 CVE(有时会为提供商创建一个特定的漏洞标识符,但通常首选 CVE 标识符),允许公开引用该问题以及可用的修复/缓解措施。
如果提供商未能与研究人员妥善合作,可能会出现以下结果:
在这种情况下,漏洞始终会引用到 CVE 全球数据库中,该数据库通常被检测工具用作几个输入源之一。
2. 完全披露¶
在此查看说明,在名为“计算机”的“计算机安全”部分中。
研究人员决定在 Full Disclosure 邮件列表、Exploit-DB 等服务上发布所有信息,包括利用代码/方法。
在这种情况下,并非总是创建 CVE,因此漏洞并非总是在 CVE 全球数据库中,这可能导致检测工具对此类漏洞视而不见,除非这些工具使用其他输入源。
关于安全问题处理决定的说明¶
当检测到安全问题时,可以决定接受安全问题所带来的风险。然而,此决定必须由公司的首席风险官(可退回至首席信息安全官)根据已分析问题的开发团队的技术反馈(参见“案例”部分)以及 CVE 的 CVSS 评分指标做出。
案例¶
当检测到安全问题时,开发团队可能会遇到以下小节中介绍的其中一种情况(在本备忘录的其余部分中称为“案例”)。
如果漏洞影响到传递性依赖项,则将在项目的直接依赖项上采取行动,因为对传递性依赖项采取行动通常会影响应用程序的稳定性。
对传递性依赖项采取行动需要开发团队完全理解从项目第一级依赖项到受安全漏洞影响的依赖项之间的完整关系/通信/使用情况,这项任务非常耗时。
案例 1¶
背景¶
提供商已发布组件的修补版本。
应用此方法的理想条件¶
对于使用受影响依赖项的应用程序功能,存在一套自动化单元、集成、功能或安全测试,可用于验证该功能是否正常运行。
方法¶
步骤 1
在测试环境中更新项目中依赖项的版本。
步骤 2
在运行测试之前,有两种可能的输出路径:
- 所有测试成功,因此可以将更新推送到生产环境。
- 一个或多个测试失败,有几种可能的输出路径:
- 失败是由于某些函数调用发生变化(例如,签名、参数、包等)。开发团队必须更新其代码以适应新库。完成后,重新运行测试。
- 已发布的依赖项存在技术不兼容(例如,需要更新的运行时版本),这导致以下操作:1. 向提供商提出问题。2. 在等待提供商反馈的同时应用案例 2。
案例 2¶
背景¶
提供商告知团队,修复该问题需要一段时间,因此修补版本在几个月内都无法提供。
应用此方法的理想条件¶
提供商可以与开发团队共享以下任何信息:
- 利用代码。
- 受漏洞影响的函数列表。
- 阻止该问题被利用的变通方法。
方法¶
步骤 1
如果提供了变通方法,则应在测试环境中应用并验证,然后部署到生产环境。
如果提供商向团队提供了受影响函数的列表,则必须用保护性代码封装对这些函数的调用,以确保输入和输出数据是安全的。
此外,安全设备,如 Web 应用程序防火墙(WAF),可以通过参数验证和为特定库生成检测规则来保护内部应用程序,从而处理此类问题。然而,本备忘录的重点是应用程序层面,以便尽可能地在源头修补漏洞。
使用 Java 代码的示例,其中受影响的函数存在远程代码执行问题
public void callFunctionWithRCEIssue(String externalInput){
//Apply input validation on the external input using regex
if(Pattern.matches("[a-zA-Z0-9]{1,50}", externalInput)){
//Call the flawed function using safe input
functionWithRCEIssue(externalInput);
}else{
//Log the detection of exploitation
SecurityLogger.warn("Exploitation of the RCE issue XXXXX detected !");
//Raise an exception leading to a generic error send to the client...
}
}
如果提供商没有提供关于漏洞的任何信息,可以跳过本案例的“步骤 2”,直接应用案例 3。我们在这里假设至少提供了 CVE。
步骤 2
如果提供商向团队提供了利用代码,并且团队围绕易受攻击的库/代码制作了安全封装,则执行利用代码,以确保该库现在是安全的并且不会影响应用程序。
如果您的应用程序存在一套自动化单元、集成、功能或安全测试,请运行它们以验证添加的保护代码不会影响应用程序的稳定性。
在项目的 README 中添加注释,解释该问题(指明相关的 CVE)在等待修补版本期间已得到处理,因为检测工具将继续对此依赖项发出警报。
注意:您可以将依赖项添加到忽略列表,但此依赖项的忽略范围必须仅涵盖与该漏洞相关的 CVE,因为一个依赖项可能受到多个漏洞的影响,每个漏洞都有其自己的 CVE。
案例 3¶
背景¶
提供商告知团队无法修复此问题,因此根本不会发布修补版本(也适用于提供商不想修复此问题或根本不回复的情况)。
在这种情况下,提供给开发团队的唯一信息是 CVE。
注意事项
- 这种情况非常复杂且耗时,通常作为最后手段使用。
- 如果受影响的依赖项是一个开源库,那么我们开发团队可以创建补丁并提交拉取请求——这样我们既可以从源头保护我们的公司/应用程序,也可以帮助其他人保护他们的应用程序。
应用此方法的理想条件¶
没有具体条件,因为这里我们处于“自行修补”的情况。
方法¶
步骤 1
如果我们由于以下任一情况处于此案例,那么最好开始并行研究以寻找另一个维护更好的组件,或者如果它是一个有支持的商业组件,那么在您的首席风险官(可退回至首席信息安全官)的帮助下对提供商施加压力:
- 提供商不想修复该问题。
- 提供商根本不回复。
在所有情况下,我们现在都需要处理此漏洞。
步骤 2
既然我们知道易受攻击的依赖项,我们也就知道它在应用程序中的使用位置(如果它是传递性依赖项,那么我们可以使用IDE内置功能或所使用的依赖项管理系统(Maven、Gradle、NuGet、npm 等)来识别使用它的第一级依赖项)。请注意,IDE 也用于识别对该依赖项的调用。
识别对此依赖项的调用是第一步,但还不够。团队仍然缺乏关于需要执行何种修补的信息。
为了获取这些信息,团队使用 CVE 内容来了解哪种类型的漏洞影响了该依赖项。description
属性提供了答案:SQL 注入、远程代码执行、跨站脚本、跨站请求伪造等。
在识别上述两点后,团队就知道了需要采取的修补类型(带有保护代码的案例 2)以及添加位置。
示例
团队有一个应用程序使用 Jackson API,其版本受 CVE-2016-3720 影响。
CVE 的描述如下:
XML external entity (XXE) vulnerability in XmlMapper in the Data format extension for Jackson
(aka jackson-dataformat-xml) allows attackers to have unspecified impact via unknown vectors.
根据这些信息,团队确定必要的修补措施将是在传递给 Jackson API 的任何 XML 数据上添加预验证,以防止XML 外部实体(XXE)漏洞。
步骤 3
如果可能,创建一个模拟漏洞的单元测试,以确保补丁有效,并能持续确保在项目演进过程中补丁始终存在。
如果您的应用程序存在一套自动化单元、集成、功能或安全测试,请运行它们以验证补丁不会影响应用程序的稳定性。
案例 4¶
背景¶
在以下情况之一中发现易受攻击的依赖项,而提供商对此漏洞不知情:
- 通过在互联网上发现完全披露的帖子。
- 在渗透测试期间。
应用此方法的理想条件¶
供应商在被告知漏洞后与您合作。
方法¶
步骤 1
通过与提供商分享帖子来告知他们漏洞。
步骤 2
利用完全披露帖子或渗透测试人员的利用反馈信息,如果提供商合作,则应用案例 2;否则,应用案例 3。此时,团队需要分析完全披露帖子/渗透测试人员的利用反馈信息,而不是分析 CVE 信息。
工具¶
本节列出了可用于分析项目所用依赖项以检测漏洞的几种工具。
在选择易受攻击依赖项检测工具的过程中,务必确保该工具:
- 使用多个可靠的输入源,以处理两种漏洞披露方式。
-
支持将组件上报告的问题标记为误报。
-
免费
- OWASP Dependency Check:
- 全面支持:Java, .Net。
- 实验性支持:Python, Ruby, PHP (composer), NodeJS, C, C++。
- NPM Audit
- 全面支持:NodeJS, JavaScript。
- 可通过此模块获取 HTML 报告。
- OWASP Dependency Track 可用于管理组织内的易受攻击依赖项。
- ThreatMapper
- 全面支持:基础操作系统,Java,NodeJS,JavaScript,Ruby,Python
- 目标:Kubernetes(节点和容器),Docker(节点和容器),Fargate(容器),裸机/虚拟机(主机和应用)
- OWASP Dependency Check:
- 商业
- Snyk(提供开源和免费选项)
- 全面支持多种语言和包管理器。
- JFrog XRay:
- 全面支持多种语言和包管理器。
- Renovate(可检测旧依赖项)
- 全面支持多种语言和包管理器。
- Requires.io(可检测旧依赖项 - 提供开源和免费选项)
- 全面支持:仅限 Python。
- Snyk(提供开源和免费选项)