关于 "木马源 "攻击

作者: Russ Cox
来源: https://research.swtch.com/trojan

有一篇论文正在流传,并附有一个漂亮的网站,作者在其中描述了一种软件供应链攻击,他们称之为 "木马源。无形的漏洞"。简而言之,如果你使用包含Unicode LTR和RTL代码点的注释,控制文本是从左到右还是从右到左,你可以使代码在标准Unicode渲染中看起来与忽略注释的程序不同。

作者声称这是 "一种新型的攻击","人类代码审查员无法直接感知","构成了直接的威胁",他们建议编译器应该 "升级以阻止这种攻击"。这些都不是真的。

攻击是旧的

首先,这些攻击并不新鲜。这里有一个2017年的Go例子,一个2018年的Rust例子,一个2019年的C++例子,以及一个2020年的Ruby例子

变化是可见的

第二,从技术上讲,攻击不能被人类代码审查员直接感知,但只是在计算机中的任何程序都不能被人类直接感知的意义上(当然,使用磁化针和稳定的手的真正的程序员除外)。相反,我们建立了一些工具,将代表我们程序的电荷或磁化粒子转换为一些更容易识别的形式,如灯光的图案。当然,我们可以完全控制这些程序所使用的确切转换,因此也可以完全控制它们使我们能够感知的东西,这个事实我将在后面再谈。

(此外,正如Hacker News上所指出的,任何能够语法突出评论的编辑器都足以检测到论文中的例子!)。

威胁不是直接的

第三,这些攻击不会产生直接的威胁,至少不会产生新的威胁。论文中的攻击模型假设你从不被信任的人那里获取对你的代码的修改。不是每个人都会这样做的!而且,做了这些修改的人通常也不会去做。而那些接受这些修改的人通常不会仔细阅读代码,所以这种攻击是必要的。例如,在事件流事件中,许多人关注事件流被社会工程劫持,而很少有人关注恶意代码只包括在一个 "最小化 "的JavaScript文件中而被隐藏起来,如果Copay的作者在升级他们的依赖关系时错过了这一事实,如果他们根本没有看这些文件。也许最重要的是,如果你让不信任的人对你的代码进行任意修改,他们可能会找到比使用LTR/RTL代码点更微妙(和可否认的!)的方法来隐藏恶意修改。

编译器是错误的修地点

最后,编译器不应该被 "升级 "来阻止攻击。修复编译器只是关闭了许多开放的门中的一个。那么汇编器呢?构建和配置文件分析器呢?一般的YAML解析器呢?还有那些以某种方式执行允许注释或引号字符串字面的文本文件内容的其他可能的程序呢?

例如,Rust项目今天发布了1.56.1,改变了rustc,不允许Rust源文件中的LTR/RTL代码点。但据我所知,cargo还没有更新,这意味着类似的攻击可能仍然可以使用Cargo.toml中的注释和字符串字面来进行。

仅仅考虑构建配置文件,关闭所有的门将意味着更新与BUILD.bazel、CMakefile、Cargo.toml、Dockerfile、GNUmakefile、Makefile、go.mod、package.json、pom.xml、requirements.txt以及很多很多相关的程序。而且,这还只是构建配置。如果要求每一个解释文本文件的程序都被修改为排除某些Unicode代码点的列表,这将是一个无限制的工作量。

即使排除 "坏的 "Unicode代码也是相当复杂的。下一个问题是同音字攻击,使用看起来相同但不相同的字符。

改变编译器也可以说是一种错误的安全感。一般来说,对于几乎所有的好坏定义,编译器都不可能分辨出代码是好是坏。即使编译器拒绝LTR/RTL代码点,它也无法拒绝攻击者可能引入的许多更微妙的变化。

答案是适当的审查

我们不应该改变编译器,而应该利用我们必须使用工具来为我们渲染程序的事实--像文本编辑器和代码审查网站这样的工具。我们应该确保我们在使用这些工具时,也要确保它们的渲染器能使可疑的Unicode使用更容易看到。这些工具比解释或执行文本文件内容的程序要少得多:大多数开发工作将只有一个审查工具和几个常见的编辑器。

让LTR/RTL代码点可见对于审查工具来说特别重要,GitHub现在在PR中警告这些字符是件好事。另一方面,博文中建议在VSCode中使用查看UTF-8文件作为CP 437来 "看到 "Unicode序列是一种笨拙的做法。希望VSCode也能很快在UTF-8模式下增加一个适当的警告和可见的指示器。

总结

综上所述:这是一个老的、已经知道的错误。源代码的改变几乎是不可见的:许多程序今天可以看到它们,而且毫无疑问,明天会有更多的程序可以看到它们。这里没有新的威胁:可以修改你运行的代码的人已经可以做很多破坏了,而这些破坏没有足够的人注意到,而且可以在没有Unicode技巧的情况下任意地变得微妙。在每个编译器中进行修复,既费事又不够好:它忽略了所有其他执行文本文件指令的程序。相反,对Unicode技巧的正确回答是适当的代码审查和依赖性卫生,这将处理更广泛的问题,完全包括这个问题,特别是使用审查工具,突出可疑的Unicode,这并不限于LTR/RTL攻击。

这篇论文的作者显然做了很好的宣传工作。在这一点上为他们点赞。但我担心的是,这篇论文得到的关注和回应总体上会分散人们对更有用的安全工作的注意力。我们应该把这些注意力和反应转到改进一般的代码和依赖性审查上来。

对这个相对较小的问题进行喘息式报道的最恶劣的例子是Brian Krebs的标题:"特洛伊木马源码 "漏洞威胁到所有代码的安全。想象一下,如果他参加了Ken Thompson的图灵奖讲座,会有怎样的报道?那是一个看不见的漏洞!(为了记录在案,早在2013年,Ken就告诉我,被屏蔽的编译器实际上是存在的,并且已经被部署了,但它有一个微妙的错误,暴露了后门:复制代码每次复制自己时都会给字符串增加一个额外的/0。这使得编译器的二进制文件每次重建时都会增加一个字节。最终,有人注意到并调试了正在发生的事情,在 "打印汇编 "编译模式完全没有插入后门这一事实的帮助下,所有痕迹都被清除了。或者说,我们相信是这样的)。

热门相关:骑士归来   刺客之王   第一神算:纨绔大小姐   照见星星的她   寂静王冠