CVE(常见漏洞和暴露)扫描对于保护您的软件应用程序至关重要。然而,随着软件堆栈的复杂性不断增加,识别和解决所有 CVE 可能具有挑战性。当今 CVE 扫描的最大问题之一是误报的普遍存在,即在生产应用程序中未使用的程序包中发现漏洞。
重要的是要记住,即使您获得了所有软件包的完整列表以及在这些软件包中找到的所有 CVE 的完整列表,也可以肯定并非所有这些都与您的应用程序相关。 CVE 可能位于您的代码中未使用的函数中,或者位于您甚至不调用的库的一部分中。它可能处于暂时依赖关系中,仅由于未修补的依赖关系列表而被调用,并且根本不在代码中使用。即使您知道 CVE 属于您使用的库的一部分,也不能保证 CVE 实际上可以在您的应用程序中利用。有些漏洞利用需要极端条件才能被黑客利用,包括按顺序组合 3 个或更多 CVE、正确的堆栈和正确的基础设施。由于您仍然需要仔细查看从扫描中获得的每个 CVE,因此您会发现筛选获得的 CVE 数量是多么重要,这样您在返回之前就不会出现警觉疲劳或 CVE 倦怠实际构建应用程序的下一个功能。
在本文中,我将提供一些可能的解决方案来减少 CVE 扫描中的误报,旨在减少您需要处理的 CVE 总数。我将首先讨论识别包的挑战,然后继续介绍将包文件映射到包名称的数据库。我还将讨论可能导致误报的范围和代码路径问题。
让我们首先看看 CVE 是如何识别的。
神秘包和缺失的 CVE
Mitre Corporation 是一家美国非营利组织,负责 CVE® 计划。该计划的 使命是识别、定义和分类公开披露的网络安全漏洞。其工作原理是,一旦发现漏洞,您就填写一份表格,如果发现的结果得到证实,就会为该漏洞提供一个新的 CVE 标识符,并将其添加到公共 CVE 数据库中。
考虑到 CVE 的列出方式,CVE 扫描的主要挑战之一是正确识别包和库。当有人发现包或库中的漏洞时,他们会用他们熟悉的包名称和版本列出它。当然,并非所有工具都使用相同的命名约定,包名称也没有现有的全球标准。众所周知,“命名问题”非常严重,以至于多个论坛和思想团体长期以来一直在努力寻找共同的解决方案。举个例子,这里是 OWASP提出的解决方案 对于这个问题,因为它涉及到创建 物料清单。通常,扫描工具依赖于它们所提供的源(例如构建或编译的工件)来获取它们在扫描结果中提供的包名称,并且这些源并不总是可靠的。例如,包装和改编可能会导致难以识别实际的包装。此外,某些包文件可能不会留下其安装程序包的任何痕迹,例如 Docker COPY 命令。
为了解决这些问题,我们在 抄写员安全,建议为您的应用程序创建一个数据库,将包文件映射到包名称。即使包名称不同,如果是同一个包,文件和文件哈希值也将是相同的。通过这样做,您可以跳过涉及包装器和改编的问题,并确定需要解决的实际包。此方法可以节省 CVE 修复过程中的时间和精力。自从 抄写平台 已经识别出与最终映像中包含的每个包关联的文件,创建这样的数据库是下一个逻辑步骤。我们希望 CVE 扫描不需要依赖于 CVE 列出的名称和版本,而是依赖于包中包含的实际文件。
你是我的妈妈吗?
在处理 Docker 镜像的最终构建时,现在的常见做法是不要从头开始。拥有一个坚实的起点(例如已建立的基础映像),使开发人员可以专注于其应用程序的构建部分,而不是开始规划其需要运行的环境。使用 Docker 镜像的挑战之一是了解它们的来源和依赖性,特别是当涉及到最终镜像所构建的父镜像(除了基础镜像)时。
父镜像是我们用来解释 Docker 镜像最接近的“活着的亲戚”的概念。镜像构建在不同的层中,因此,假设我使用已知的基础镜像,例如 Alpine、Debian 或 Ubuntu,并在其之上构建我的应用程序层。在这种情况下,我最接近的“父母”将是该基本图像。但是,如果我工作的公司有一个不同的起点,其中包括一个基础映像以及在所有公司映像都必须使用的安全工具之上的更多层,该怎么办?在这种情况下,我的父映像将是该公司模板,并且我还能够识别构建该模板的基础映像。
父映像是软件供应链的重要组成部分,因为它为应用程序及其依赖项提供了基础。本质上,Docker 镜像不包含太多有关其父镜像或基础镜像来源的信息,因此很难验证其完整性、了解其漏洞并验证其许可证。
为了解决这个问题,Scribe 开发了一个开源工具和服务,称为 父图像 检测 Docker 映像最近的扫描父级。该工具可用于识别 Docker 映像的父映像,这是降低风险的关键推动因素:
首先,通过识别基础镜像,可以验证其完整性并确保其未被篡改或泄露。这对于维护应用程序的安全性和稳定性非常重要。
其次,通过了解哪些漏洞源自父映像以及哪些漏洞源自应用程序层本身,我们可以更有效地确定漏洞的优先级并对其进行管理。这意味着与应用程序层中的 CVE 相比,链接到基础映像或父映像的 CVE 不太紧急(并且并不总是由您负责修复)。
此外,通过识别父映像,可以验证其许可证并确保符合法律和内部政策要求。
ParentImage 开源工具包含一个可更新的 Docker 映像扫描数据库。您可以派生它并在内部完全使用它,但我们希望人们能够扫描他们的 Docker 镜像并将该信息发送给我们以包含在数据库中。数据库中包含的图像扫描越多,该工具能够识别的“父母”就越多。目前,所包含的数据库拥有所有已建立的基础图像的完整列表,作为概念证明。作为一个开源工具,尝试它不需要任何成本,因此如果您使用 Docker 映像,我鼓励您考虑使用此工具作为解决不相关 CVE 原因的一种可能的补救措施。
我应该扫描还是应该跳过?
CVE 扫描的另一个挑战是范围问题。范围界定是指扫描的文件和包的位置 - 扫描中应包含哪些内容以及可以安全地忽略哪些内容。有时,在应用程序的生产版本中实际未使用的包中会发现 CVE。例如,可能由于对某些测试框架的间接依赖而安装软件包。为了解决这个问题,扫描器需要评估应用程序文件的范围并识别使用中的间接依赖关系。
OWASP(开放全球应用程序安全项目)插件有一些很好的工具示例,可以帮助解决范围问题。 OWASP 依赖性检查例如,可以分析应用程序的依赖关系并在应用程序依赖关系图的上下文中识别 CVE。通过这样做,它可以识别哪些 CVE 在生产应用程序中正在使用,哪些没有。
无论数量有多少,您仍然需要解决您的 CVE
如果没有其他工具能够告诉您应用程序在哪里容易受到黑客攻击、后门和其他此类问题的影响,CVE 扫描仍然是解决潜在问题的一个非常基本的选项。问题是,除非您验证扫描中显示的 CVE 是否是一个实际问题,否则它代表着监管机构、第三方和用户等可以用来对付您的威胁。
以安全性和透明度的名义,您需要检查每个潜在问题并证明它不是问题,与您的应用程序无关,或者它是一个潜在问题并且您正在努力修补它。事实上,许多 CVE 是从外部(通常是开源)软件包进入您的应用程序,这意味着即使您将其识别为潜在的漏洞,您可能仍然需要软件包维护人员的帮助来修补它。
由于与每个 CVE 相关的所有这些工作,难怪您希望在下一次 CVE 扫描中获得尽可能小的数字。使用本文中概述的一些建议可能有助于使解决漏洞的艰巨任务变得更容易管理。
如果您有其他开源或免费工具来解决这个问题,我们很乐意听到。在评论中告诉我们,并与社区分享您如何处理堆积如山的漏洞。
此内容由领先的端到端软件供应链安全解决方案提供商 Scribe Security 为您提供 - 为整个软件供应链中的代码工件以及代码开发和交付流程提供最先进的安全性。 了解更多