当前位置: 首页 > 科技观察

Go如何应对供应链攻击?

时间:2023-03-12 14:11:55 科技观察

Go的官方博客描述了他们对供应链攻击的缓解措施。据说Go的工具链和设计中包含了降低各个阶段被攻击风险的考虑。所有构建都是“锁定”的——外部更改(例如发布新版本的依赖项)不会影响Go构建。与大多数其他包管理器使用的配置文件不同,Go模块没有单独的约束列表和用于锁定特定版本的锁定文件。参与Go构建的每个依赖项的版本完全由主模块的go.mod文件确定。从Go1.16开始,以上是默认完成的,如果go.mod不完整,构建命令将失败。唯一会改变go.mod的命令是goget和gomodtidy。这些命令通常不会自动运行或在CI中运行,因此对依赖树的此类更改通常是经过深思熟虑的,并且可以在代码审查阶段发现。这对于安全性非常重要,如果一个模块被破坏并发布了一个新的恶意版本,在该依赖项被明确更新之前没有人会受到影响,从而使生态系统有时间审查更改和检测事件。版本内容永不改变确保第三方不会影响构建的另一个关键属性是模块版本的内容是不可变的。因为如果破坏依赖关系的攻击者可以重新上传现有版本,他们可以自动破坏依赖该依赖关系的所有项目。这正是go.sum文件的用途。它包含有助于构建的每个依赖项的加密哈希列表。另外,不完整的go.sum会报错,只能用goget和gomodtidy修改。因此,对它的任何修改都会伴随着主观依赖性的改变。VCS是真实的来源大多数项目在开发过程中使用版本控制系统(VCS),而在其他生态系统中,这些项目也需要上传到中央包存储库(例如npm)。这意味着可能会破坏两个帐户,即VCS主机和中央软件包存储库。后者较少使用,更容易被忽视。这也意味着更容易在上传到存储库的版本中隐藏恶意代码,特别是如果源代码作为上传的一部分被例行修改。Go没有中央包存储库帐户之类的东西。包的导入路径嵌入了直接从VCSgomod下载中获取其模块所需的信息,其中VSC上的标签定义了模块版本。只构建代码,不执行Go工具链有一个明确的安全设计目标:获取或构建代码都不会导致代码执行,无论代码是不受信任的还是恶意的。如果您正在执行二进制文件或测试仅使用其依赖项子集的包模块,这是一种有意义的风险缓解措施。例如,如果example.com/cmd/devtoolx在macOS上构建和执行,那么对Windows的依赖或对example.com/cmd/othertool的依赖不太可能危及您的机器。在Go中,不为特定构建贡献代码的模块对构建没有安全影响。最后(可能也是最重要的)供应链攻击风险缓解“复制依赖项”也是最不技术性的:Go有拒绝大型依赖树的文化,并且更喜欢复制而不是添加新的依赖项。这可以追溯到一句Go谚语:“alittlecopyingisbetterthanalittledependency”(复制优于依赖)。Go模块以其“零依赖”标签而自豪。如果一个开发者需要使用一个库,他会发现这个库不会让他依赖其他作者和所有者的几十个模块。这意味着可以仅使用少量依赖项来构建丰富、复杂的应用程序。毕竟再好的工具也无法消除重用代码的风险,所以最有效的缓解措施总是只有一个小的依赖树。本文转自OSCHINA文章标题:Go如何应对供应链攻击?本文地址:https://www.oschina.net/news/189878/golang-supply-chain