依赖性应直接从版本控制系统获取
在过去一个月中,我在新的 $dayjob 中一直在编写 Ruby。在过去十年中大部分时间我都在编写 Go,能够体验这种有趣的变换环境。我以前也编写过 Ruby(许多年前),我无法真的告诉你哪种语言更“好” —— Ruby 在几乎所有方面都与 Go 非常不同,我发现两者在各自的方式中都能有效地完成任务。有一个方面我觉得 Go 明显更好,那就是依赖管理;特别是安全性方面。Go 并不是神奇地免于恶意依赖,但它在这方面的抵抗力更强,主要是因为没有“发布包”的步骤。在 Go 中,依赖通过 URL 识别,例如 github.com/user/pkg。Go 会识别所使用的版本控制系统(在这种情况下是 git),并获取你在 go.mod 文件中指定的 tag 或 commit。go.mod 文件既作为依赖规范,也作为“锁定文件”。它列出了确切版本;没有 ~>1.1。它包括直接和间接依赖,并列出了你的完整依赖树(go 命令会写入 go.mod)。会检查所有文件的哈希与 sum.golang.org 上的已知哈希进行匹配,以防止标签被替换,并使用代理防止代码库被左填充。Go Modules 还有更多方面,包括安全功能,但出于本文目的我将略过它们。相关的部分是“依赖通过 URL 识别,代码直接从 VCS 获取,并且对于直接和间接依赖都如此”。审计和更新依赖很简单:我通常通过 forge Web UI 执行 git log -p old..new,阅读所有提交,并更新 go.mod 文件。我没有很多依赖,并且那些依赖变化不大。通常速度非常快。我不需要在这里进行仔细的深入审查;只需寻找可疑的内容。在一个 globbing 库中像 exec.Command(..) 或 http.Post(..) 这样的东西会很显眼。很难真正隐藏内容。作为一个独立开发者,我多年来一直这样做。对于一些项目,依赖树会更大,这会变得更耗时,但并不困难或令人困惑。依然很简单,只是需要一点时间。对于 Ruby 来说,情况则不同,因为它有一个“发布包”的步骤:你创建一个 .gem 存档并将其上传到 rubygems.org。你可以在里面放任何东西 —— 不保证 .gem 内容与源代码库相对应。为了审计它,我需要做类似这样的操作:curl -s https://rubygems.org/downloads/example-2.7.5.gem >old.gem curl -s https://rubygems.org/downloads/example-2.8.2.gem >new.gem mkdir old new tar xf old.gem -C old tar xf new.gem -C new (cd old && tar xf data.tar.gz) (cd new && tar xf data.tar.gz) diff -urN old new 这或许有效,但远非简单。单个提交丢失,通常审计难度更大。在某些情况下,diff 足够小,因此没问题。在其他情况下,这可能很大,而没有访问提交信息是个痛苦。我也能完全想象自己会对我审计的内容产生混淆。我想,进行这种审计的人数非常少,因为这实在太麻烦。这并不是 Ruby 特有的:许多(大多数?)包系统都是这样工作的。我看到的几乎所有“侧信道攻击”,也许更准确地说是“包发布攻击”。它们依赖于在“发布包”的步骤中注入某些东西。无论是 RubyGems、npm、PyPI、.tar.gz FTP 下载还是其他东西都相对不重要。实际上源代码库被攻破的情况很少,因为它太明显。你需要至少稍微隐藏你的攻击才能有效。最近的 npm 破坏都依赖于获得 npm 账户的访问权限并在发布的包中注入某些东西。xz 的源代码库中有一些漏洞代码,但是无害的,隐藏在一个二进制测试文件中,仅在修改后的 .tar.gz 发布中激活。2018 年,event-stream 增加了对 flatmap-stream 的依赖,后者在发布的 npm 包的 index.min.js 中包含恶意代码。这指向第二个问题:包含“编译”资源的包。TypeScript 生成的 JavaScript 不是完全无法读取的,它的确比原始的 TypeScript 更难阅读和审计。更不用说压缩文件或二进制数据块了。在 Ruby 中这不是一个大问题,但在 npm 中却是一个更大的问题。上周,RubyGems 添加了冷却选项和“对最关键 gem 的 AI 辅助漏洞扫描”。这作为短期措施并不好,但我觉得更合适的解决方案是重新考虑整个“发布包”模型。它缺乏所需的透明度。AI 工具并不会神奇地解决这个问题。我可能会在二十年前自己创建类似 RubyGems 的东西。分发 .tar.gz 文件是 SourceForge 上运作的主要方式,许多项目没有公开可访问的 VCS 仓库,或者根本没有。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡