大多数网络攻击都利用公开已知的漏洞。许多程序员可以使用持续集成/持续部署 (CI/CD) 或 DevOps 技术来自动化构建。但是,我们如何自动化安全缺陷的检查,这些缺陷每小时都会在不同的免费和开源库中出现?现在有许多方法可以在构建应用程序时找出库的错误版本。
本文将重点介绍 Python,因为它拥有一些用于检查依赖项安全性的复杂工具。特别是,本文探讨了 Project Thoth,因为它汇集了许多此类工具,以自动化 Python 程序构建,并将安全检查作为解决过程的一部分。作者之一 Fridolin 是 Thoth 的主要贡献者。
自动化安全工作的输入
本节列出了向公众提供有关漏洞信息的努力。它侧重于与本文主题相关的工具:开源 Python 库中的漏洞报告。
通用漏洞和披露 (CVE) 计划
任何关于软件安全的讨论都必须从全面的 CVE 数据库开始,该数据库汇集了数千名分散的研究人员发现的缺陷。本文中的其他项目在很大程度上依赖于此数据库。它由美国国家标准与技术研究院 (NIST) 维护,并由 MITRE(一家专门从事开源软件并由美国政府支持的非营利性公司)策划添加内容。CVE 数据库为许多相关项目提供数据,例如 CVE Details 统计站点。
人员或自动化工具可以找到与结构化格式的安全漏洞相关的确切软件包和版本,以及解释漏洞的结构化程度较低的文本,如下所示。

(Fridolín Pokorný 和 Andy Oram,CC BY-SA 4.0)
Python Packaging Authority 的安全工作
Python Packaging Authority (PyPA) 是为 Python 语言中的开源软件包创建最佳实践的主要组织。来自许多公司的志愿者支持 PyPA。PyPA 的安全相关举措是使 Python 变得健壮的重大进步。
PyPA 的 Advisory Database 以机器可读的形式策划 Python 软件包中的已知漏洞。另一个项目 pip-audit(由 PyPA 支持)审核应用程序需求并报告所用软件包中的任何已知漏洞。pip-audit 的输出可以是人类可读格式和 JSON 等结构化格式。因此,自动化工具可以查阅 Advisory Database 或 pip-audit,以警告开发人员其依赖项中的风险。
PyPI 的维护者 Dustin Ingram 制作的 视频解释了这些项目是如何工作的。
开源洞察
一项名为 开源洞察的倡议试图通过以结构化格式提供有关流行语言生态系统中依赖项的信息来帮助开源开发人员。此类信息包括安全公告、许可证信息、库的依赖项等。
为了稍微练习一下开源洞察,我们查找了流行的 TensorFlow 数据科学库,并发现(在撰写本文时)它在 PyPI 上有一个 安全公告(见下文)。单击“更多详细信息”按钮会显示可以帮助研究公告的链接(第二张图片)。

(Fridolín Pokorný 和 Andy Oram,CC BY-SA 4.0)

(Fridolín Pokorný 和 Andy Oram,CC BY-SA 4.0)
有趣的是,Node.js 软件包管理器 (npm) 提供的 TensorFlow 版本当时没有安全公告。在这种情况下使用的编程语言可能是造成差异的原因。然而,明显的矛盾提醒我们,出处可能会产生很大的影响,我们将展示用于解决依赖项的自动化过程如何适应此类问题。
开源洞察通过将 Python 软件包安装到干净的环境中来获取有关 Python 软件包的依赖项信息。Python 软件包由 pip 解析器(Python 库最流行的安装工具)安装,从 PyPI(最流行的开源 Python 库索引)安装。每个软件包的漏洞信息都从 开源漏洞数据库 (OSV) 中检索。OSV 充当分类服务,对跨多个语言生态系统的漏洞进行分组。
如果开源洞察具有 API,那将是一个非常有价值的资源;我们预计开发人员会在某个时候添加一个 API。即使目前信息仅以网页的形式提供,结构化格式也允许自动化工具抓取页面并查找关键信息,例如安全公告。
开源安全基金会的安全记分卡
软件质量(与安全性密切相关)需要基本实践,例如在将更改检入存储库之前进行回归测试、将加密签名附加到版本以及运行静态分析。其中一些实践可以自动检测,从而使安全专家能够大规模评估项目的安全性。
一项名为 安全记分卡的工作于 2020 年启动,并由 开源安全基金会 (OpenSSF) 支持,目前列出了 几十个此类自动化检查。这些检查中的大多数都依赖于 GitHub 服务,并且只能在 GitHub 中存储的项目上运行。鉴于 GitHub 在开源项目中的主导地位,该项目仍然非常有用,并且代表了更通用评级系统的模型。
Project Thoth
Project Thoth 是一种基于云的工具,可帮助 Python 程序员构建健壮的应用程序,这项任务包括安全检查以及许多其他考虑因素。Red Hat 启动了 Thoth,它在 Red Hat OpenShift 云服务中运行,但其代码完全是开源的。该项目在 Python 开发人员中建立了一个社区。开发人员可以在其他编程语言中复制该项目的创新。
一种帮助程序员查找库和构建应用程序的工具称为解析器。流行的 pip 解析器通常选择每个库的最新版本,但足够复杂,可以考虑层级结构(称为依赖关系图)中依赖项的依赖项。pip 甚至可以回溯并选择库的不同版本,以处理遍历依赖关系图找到的版本范围规范。
在选择依赖项的最佳版本时,Thoth 可以比 pip 做更多的事情。以下是 Thoth 的概述,特别关注它如何在安全性方面提供帮助。
Thoth 概述
Thoth 在安装依赖项时会考虑程序环境的许多要素:程序将在其上运行的 CPU 和操作系统、有关应用程序容器的元数据(例如 Skopeo 提取的元数据),甚至机器学习应用程序将使用的 GPU 的信息。Thoth 可以考虑其他几个变量,但您可能可以从前面的列表中猜到,Thoth 最初是为支持容器中的机器学习而开发的。开发人员在配置文件中向 Thoth 提供有关应用程序环境的信息。
环境信息有什么优势?它允许 Thoth 排除指定环境中具有已知漏洞的库版本。注意到构建失败或运行期间出现问题的开发人员可以将有关要使用或避免的依赖项版本的信息存储在称为 处方 的规范中,供 Thoth 供未来用户参考。
Thoth 甚至可以对程序及其环境运行测试。目前,它使用 Clair 对容器映像的内容运行静态测试,并存储有关发现的漏洞的信息。未来,Thoth 的开发人员计划使用 Python 代码质量管理局 (PyCQA) 的一个名为 Bandit 的项目,对具有各种库版本组合的实际应用程序运行测试。Thoth 将在每个软件包源代码上单独运行 Bandit,并在解决过程期间合并结果。
各种库的不同版本可能会导致组合爆炸(可能的组合太多,无法全部测试)。因此,Thoth 将依赖项解析建模为 马尔可夫决策过程 (MDP),以决定要运行的最有成效的子集。
有时,安全性不是首要考虑因素。例如,您可能计划在与 Internet 隔离的专用网络中运行程序。在这种情况下,您可以告诉 Thoth 优先考虑其他一些好处,例如性能或稳定性,而不是安全性。
Thoth 将其依赖项选择存储在锁定文件中。锁定文件“锁定”特定依赖项的特定版本。如果没有锁定文件,细微的安全漏洞和其他错误可能会悄悄潜入生产应用程序。在最坏的情况下,如果不锁定,用户可能会遇到所谓的 “依赖项混淆攻击”。
例如,解析器可能会选择从具有错误版本的索引中获取库,因为解析器通常从中获取依赖项的索引暂时不可用。
另一个风险是,攻击者可能会在索引中提高库的版本号,从而导致解析器选择该版本,因为它是最新的版本。所需的版本存在于不同的索引中,但因偏爱看起来更新的版本而被忽略。
总结
Thoth 是一个复杂且不断增长的开源工具集合。其依赖项解析背后的基本原则可以为其他项目提供灵感。这些原则是
- 解析器应通过抓取 CVE 数据库等网站、运行静态检查以及通过任何其他信息来源来例行检查漏洞。结果必须存储在数据库中。
- 解析器必须查看依赖项的依赖项,并在发现某些错误或安全缺陷需要更改解析器先前做出的决定时进行回溯。
- 解析器的发现和使用解析器的开发人员传递回的信息应存储并在未来的决策中使用。
简而言之,凭借当今可用的关于安全漏洞的大量信息,我们可以自动化依赖项解析并生成更安全的应用程序。
1 条评论