从 SolarWinds 吸取的经验教训 – 对第三方库进行评估

On By Jacob Emmert-Aronson1 Min Read
Lessons from SolarWinds – Evaluating third-party libraries

2020 年 12 月,SolarWinds 宣布其 Orion 产品遭到大规模网络攻击,导致攻击者利用后门入侵了很多 SolarWinds 客户的基础设施,其中包括多家政府机构。 这次攻击波及范围之广引起了外界对供应链漏洞和第三方依赖项对软件系统安全的影响的极大关注。 虽然这些威胁都是常规威胁,但最近安全事件频发,导致此方面的审查日益增多,各企业强烈渴望改善自身安全状况,避免成为下一个攻击目标。 作为软件工程团队,与供应链之间的联系主要在于选择外部库并将其合并到自身的应用中。 外部库维护良好可以为开发工作带来极大便利,让您专注于发展自身产品的核心竞争优势,而不必重新实现通用功能,从而为工程师节省大量时间。 相反,这些库维护不当可能会造成使用困难,引入安全漏洞,给您的企业和客户带来风险。在极端情况下,甚至还会干扰与您的服务不相关的部分的正常运作,或者破坏您的整个架构。 我采用众多考量因素来评估第三方库的工程实践稳健性及其可能对安全性产生的影响。本文将对这些考量因素进行简要概述。 这些方法只是提供一个切入点,而不是一体适用的解决方案。 您需要找到能够满足您自身需求的方法。 虽然在该领域没有一劳永逸的解决方案,但是如果能够确保您的项目只使用高质量的依赖项,可以极大地减小您的受攻击面,并使您的产品更易于扩展和维护。

库的作用域

这个首要考量因素非常关键,因为它决定了需要或适宜进行何种程度的评估。 库提供了多少功能? 这些功能对您产品的运行有多重要? 与紧密集成到您自身代码中的大型框架相比,占用空间小的简单库不需要进行过多的审查。 对于关键功能而言,有些指示信号可能表明存在重大危险(例如很少更新),但对仅用于完成极小任务的小型库而言,这些指示信号可能属于正常或意料之中的情况。 关键问题在于您打算如何使用相应的库。 开发依赖项(例如静态分析工具或单元测试框架的组件)的风险远低于运行时依赖项。 虽然构建管道出现故障可能会导致发布延迟或给开发者带来其他短期问题,但不会直接影响用户,且通常不会对应用本身的安全构成风险。

维护历史

了解项目整体运行状况最快的方法是查看其源代码控制历史记录。 上一次发布是什么时候? 版本发布频率以及提交到源代码存储库的频率是多少? 我希望能够看到项目经常更新,因为这会让我对库在未来继续得到维护更有信心。 相反,如果项目长期处于搁置状态,那么可能会存在一些未解决的错误,或者可能出现与新版本公共依赖项甚至语言运行时本身有关的兼容性问题。 查看库的更新日志也非常重要。 有时,发行页面上会描述每个版本所做的更改。 有时,源代码存储库顶层的某个文件就是更新日志。 如果不易获取这些信息,这就是一个重大危险信号。 对于从一个版本到下一个版本所做的更改以及任何向后的不兼容性,我希望能够看到清晰的描述和记录。 但是,频繁对核心功能的向后不兼容进行更改或进行错误修复也令人感到担忧,因为这表明开发者在发布之前没有做好规划和调试更改的工作。

维护者与社区的关系

更深入的评估可能涉及查看项目的问题跟踪器和其他公共通信渠道。 维护者对用户的响应情况如何? 他们是态度友好并乐于接受反馈,还是经常以驳斥的口吻进行回应? 已提交的问题与已解决的问题之间的比例是多少? 维护者是积极解决用户问题,还是任由错误报告长期累积而不予解决? 文档内容有多全面,是否能有效指导用户实施最佳实践? 是否存在围绕该项目的活跃社区? 例如,用户支持的负担是完全落在主要维护者身上,还是有其他社区成员愿意并能够分担一部分工作? 与社区保持健康关系的项目更有可能满足用户的特定需求,并快速适应不断变化的环境。

传递依赖

这项评估工作比简单计算发布频率要费力一些,但能够为我们提供一个信息宝库。 我想了解的第一件事是,一个库中存在多少附加依赖项,尤其是库中是否引入了不必要的依赖项。 如果依赖项能够为库提供关键功能,则无需担忧,但如果为了不相关的任务引入许多附加库,则需要提高警惕。 每一个附加依赖项都会增加问题的复杂性,并给供应链带来额外风险。 如果对此有疑虑,可以采用一个简单的评估方式:将库添加到 docker 容器中,并留意在此过程中添加了多少附加库。 在此方面最令人担心的问题是,当我们发现新的漏洞时,我们能否轻松更新依赖项。 因此,在评估过程中,务必留意依赖项是否有限制(即,是仅适用特定版本的库还是适用一系列版本)。 有限制的依赖项是一个大问题,因为这类依赖项会加大修补工作的难度,甚至导致为我们提供其他功能的库降级。 此外还有一个关键问题,那就是这些传递依赖存在了多长时间。 与两个月前发布的依赖项版本相比,两年前发布的版本更令人感到担忧。 同样,频繁更新以保持依赖项的新鲜度,是项目运行良好的一个标志。

跨语言的依赖项

请特别留意程序包与附加依赖项的编写语言不一致的情况(例如,在 Python 库编写 C 扩展)。 如果次要依赖项涉及您不太熟悉的语言或编程环境,则更难以评估其整体质量。 此外,不同的语言通常有不同的打包约定,混合语言项目的维护者通常并不精通运行项目使用的所有编程语言的最佳实践,因此导致修补和更新的难度更大。

加密库

加密库必须得到特别关注,因为其所涉及到的算法非常复杂性,并且此方面潜在漏洞的影响很大。 请务必对这些库进行仔细审查,确保您所依赖的库均经过全面审查并且一贯表现良好。 对于加密库,一些比较保险的选择包括用于 C 和 C++ 的 OpenSSL、用于 Java 的 BouncyCastle,以及用于 Python 的 PyCA 加密库。 您的选择可能会受到您的企业安全策略或合规性要求的限制。 请留意加密库中已知的漏洞并持续关注新发布的版本。 在所有第三方依赖项中,此类依赖项对安全性的影响最大。

代码和文档质量

此部分和下一部分的评估工作非常费力,但有时遇到风险较高的情况时,就必须进行这个级别的审查。 如果我想了解一个项目的整体代码质量,我会尝试找到使用我最了解的功能的源代码,并评估在代码库中那一小块区域的编写情况。 有时我会查看项目文档的质量,重点关注编写者的思维清晰度和有效传达复杂概念的能力。 在任何情况下,我们的目标都是确定维护者是高度关注细节还是选择偷工减料。 我们希望在项目某个部分所呈现的细节关注程度能够代表项目的整体情况。 具体而言,如果我选择查看 Python 项目对 SSL 的处理,我可能会留意以下方面:

  • 项目是使用默认的 SSL 连接参数还是尝试自定义为更安全的设置?
  • 如果是尝试自定义,那么更改是否合理?
  • 是否允许用户进行其他自定义?
  • 如果允许用户进行自定义,那么是重新使用 Python 标准库的 SSLContext 对象还是尝试重新发明轮子?

在此类评估过程中,我希望看到合理的设计原则、标准习语的使用,以及作者可以预见潜在的用户需求并提供适当的可扩展性来解决这些需求。

漏洞处理

我之所以将这项考量因素放在最后,是因为我通常在评估过程中逐渐积累对这方面的考察,在初步评估时就关注此因素的作用不大。 此外,此因素在很大程度上取决于特定库的使用范围和安全相关程度。 但是,在决定是继续使用现有库还是尝试迁移到替代库时,这确实是一个需要考量的因素。 简而言之,我会尝试评估项目维护者在修补漏洞方面的响应能力,以及在我们自身的部署中能否轻松从这些补丁中受益。 如果一个项目经常出现漏洞披露,则确实有些令人担忧,但这很可能是因为它使用广泛而且与安全性密切相关,而不一定是因为整体代码质量和维护实践存在问题。 一个更好的衡量指标是考察在漏洞披露后会发生什么情况。 是否很快在新发布的版本中整合相应补丁? 发布补丁版本后,是否能够轻松完成升级? 如果项目经常出现全面更改,尤其是在更改经常会破坏向后兼容性的情况下,是否会将补丁向后移植到旧版本中? 如果库是 Linux 发行版的一部分,向后移植补丁的责任通常会落在发行版维护者而不是原始开发者身上,但打包者对库的处理也存在同样的问题(发行版通常会区别对待核心包和外围包,对核心包的维护很积极,而对外围包在跟踪上游版本时通常只会应用极少的更新)。 如果一个库的历史记录清晰地揭示其长期对漏洞处理不善或在运行中难以充分利用安全补丁,我通常会建议我的团队迁移到其他替代库。

总结性思考

评估软件项目及其周围社区的整体质量是一项基本技能,随着软件项目的相互依赖程度进一步提高,这项技能只会变得更加重要。 这也是一项高度个人化的技能,通过审查您专业领域内的库维护者所做的决策,您通常可以获得巨大的收益。 与自己构建功能相比,全面审查潜在供应商的所有细节难度更高,所以通过评估可以建立一定程度的信任,并能够采取相关措施确保他们值得信任。 归根结底,学习审查第三方依赖项是工程文化的重要组成部分,有助于确保产品的安全性和可靠性。

关于作者

Jacob Emmert-Aronson 是 Mindmeld 团队的高级工程师,该团队隶属于 Webex Intelligence 团队。 他是信息安全、开发运维 (DevOps) 和软件维护方面的知识领军者,他的专长是探究这些主题之间的交集。

有兴趣加入 MindMeld 团队? 请发送邮件至 mindmeld-jobs@cisco.com!

注册 Webex 访问我们的主页或直接联系我们,以获得帮助。 点击此处详细了解 Webex 提供的产品/服务,注册免费帐户。

About The Author

Jacob Emmert-Aronson
Jacob Emmert-Aronson Senior Engineer Cisco
Jacob Emmert-Aronson is a senior engineer on the Mindmeld team, part of the Webex Intelligence organization.
Learn more

Topics


More like this