「警惕」存在于crate中的安全风险

「警惕」存在于crate中的安全风险

本文基于最近两天在推上和社区的朋友互动而引发的思考。

起因

Rust Tg群的群主在2号发推,说他看到有人在Rust的过程宏中下载文件。

我询问以后发现是这个crate:github.com/addr-rs/addr

我仔细查看后发现,该库是用来做电子邮件域名有效性验证的。它使用了Mozilla的公共后缀列表(Public Suffix List)可靠地解析Rust中的域名和电子邮件地址。

该库在Readme里写道:

可以通过设置环境变量PSL_URL或PSL_PATH来提供自己的列表。如果您不提供自己的列表,将在构建期间从官方站点下载一个列表。

重点

重点在于文档里说的「构建期间」是在一个过程宏中完成的下载,它会从Mozilla下载了一个207k的邮件域名后缀文件,也就是PSL。

查看其源码:

这个codegen就是定义过程宏的crate,其中的process方法中就调用了在lexer包中封装好的fetch方法开始下载文件(如果没有本地列表的话)。

然后在lexer包中查看fetch的定义,看到的是调用了另一个封装好的from_url方法发起具体的下载请求。

反思

这代码写的还不错,组件职责分离,逻辑清晰,封装到位,很符合Rust的最佳实践。

就这个库而言,作者是想让用户有更完善的体验。在本地没有现成的PSL列表,就从官方帮助你下载一个。并且下载获取的数据,在宏里面也是需要用到的。这个可能不方便使用build script。

但是话说回来,在宏里下载文件,这样的脑洞,恐怕是打开了「潘多拉魔盒」。

这个addr crate的作者并没有恶意,并且很明确地在Readme里告诉你这个库的行为是什么样的。

但是,万一换个其他人呢?

能下载一个简单的文件,就可以下载其他更复杂的文件,或者是恶意文件。能下载,意味着也可以上传,意味着你可以执行某些设计好的指令(假如某些服务器的安全权限没设置好)。只要想象力丰富,在Rust的过程宏里,也许可以做出更多坏事。

不是我们要恶意揣测别人,而是,这个世界就是这么危险。

对策

所以,我们在使用Rust第三方库的时候,需要一些安全建议:

  1. 尽可能地使用知名的库。更多的人star,更多的人参与贡献。这样的库比较安全。
  2. 在使用像Addr这种star数很少的库时,需要仔细审查它的源码。(查看宏展开,推荐cargo expand插件,也有其他的插件)
  3. 然而,你可以查看一个crate的安全性,但是你很难查看它依赖的crate是否安全。这个时候就推荐使用cargo crev

重点介绍一下Crev工具。该工具可以判断你项目中依赖crate的安全性、质量和发现的问题。可以在公共的git仓库里发布可验证的review信息。通过这种方式期望在Rust生态系统中构建可信任的网络。将不会有人再受到未经审查和不受信任代码的困扰。

想想npm因为依赖包出了多少次安全事故。这个工具貌似不错,现在维护也非常积极。

使用方法:


$ cd <your-project>
$ cargo crev id gen # generate your id
$ cargo crev verify # verify your depedencies
$ cargo crev review <crate> # review a dependency
$ cargo crev db git status # check git status of your proof database
$ cargo crev db git -- ci -a # commit everything
$ cargo crev db git push # push it to your github repository
$ cargo crev trust <id> # trust someone with a given CrevId
$ cargo crev db fetch # fetch updates from all people you trust
$ cargo crev verify # verify again
$ cargo crev help # see what other things you can do


其中id是可以通过 crev gitter channel 来共享给大家的,形成信任网络。然后可以通过 cargo crev trust <id> 命令从你信任的人那里获取依赖crate。

当然,这世界上没有绝对的安全,但也无法阻碍人们追求它的脚步。

更新:

关于更多安全策略,在本文的镜像reddit英文贴中网友给出了建议 :github.com/rust-secure- , 这里存在一些相关讨论的想法。比如,crater工具在构建期禁用了网络的功能: github.com/rust-lang-nu

编辑于 2019-05-04

文章被以下专栏收录