以太坊安全分析工具对比【Slither vs. MythX vs. Securify】

安全很难。当用户的资金受到威胁时,这将变得更加困难。幸运的是,以太坊生态系统 在过去几年中已经成熟,现在有各种高质量的工具可以扫描你的以太坊智能合约中的安全漏洞, 虽然这些工具还不足以替代真正的审计。在这个教程中,我们将按介绍三种比较流行的安全分析工具 Slither、MythX和Securify,以便你可以比较它们:

用自己熟悉的语言学习 以太坊DApp开发Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart

本教程将假定你具有Python 3,Git和Solidity的经验,并按照如下步骤进行介绍:

  • 设定程序
  • 运行扫描
  • 结果分析

1、安全工具简介

让我们先简单介绍下这三种安全工具。据我所知,这些工具都不支持Vyper,它们都只能分析Solidity 编写的智能合约。

1.1 Slither

Slither由安全组织Trail of Bits开发,并将Slither描述为“用Python 3编写的Solidity静态分析框架。 它运行一组漏洞检测器,输出有关合约详情的可视信息,并提供可轻松编写自定义分析的API。

Slither使开发人员能够发现漏洞,增强他们的代码理解能力并快速进行定制分析原型。

Slither还提供了一些其他有用的工具,例如flattener,检测符合各种ERC(例如ERC20和ERC721)的能力, 并使用委托调用代理模式检查可升级合约。Trail of Bits团队还写了一些有关该工具的博客文章,你可以 在这里这里找到。

1.2 MythX

MythX(一个ConsenSys项目)可以”自动扫描以太坊和其他基于EVM的区块链智能合约中的安全漏洞。 MythX广泛的分析技术范围(包括静态分析,动态分析和符号执行)可以准确地检测安全漏洞,以提供深入 的分析报告。MythX拥有充满活力的世界级集成合作伙伴生态系统,可提高开发人员的工作效率,可在项目 生命周期的所有阶段使用。我们的安全专家团队致力于研究和改进我们用于加强代码的工具和技术。”

MythX团队拥有自己的博客,可在此处找到,以及精选的资源和工具列表。 值得指出的是,MythX是一项全面的安全服务,而不仅仅是扫描工具。

1.3 Securify

我们来看看最后一个工具Securify,由ChainSecurity开发。Securify支持38个漏洞, 实现了新颖的上下文相关静态分析,不过Securify只能分析以Solidity版本0.5.8或更高版本编写的合约。

需要注意的是,本教程中使用的是Securify v2.0,它是原始Securify的后继产品。

2、设置安全工具

如果你不愿意克隆FakerDAO项目,那么我们假设你 准备好了要进行安全分析的项目,请继续就好。FakerDAO这是一个很好的项目,因为它很简单, 部署后唯一要使用的合约Faker.sol位于contracts文件夹中。

2.1 Slither

Slither只是Trail of Bits的以太坊安全工具套件中的一个工具,因此,如果你对其余的内容感兴趣, 可以查看这里

有两种安装Slither的方法:

  • 通过Docker使用Docker安装全套工具 docker pull trailofbits/eth-security-toolbox
  • 使用Python仅安装Slither

两种方法都可以使用,但是无论如何我们稍后都将使用Python,因此这里将使用方法2。

在项目文件夹中,使用命令python3 -m venv venv创建Python虚拟环境并使用source ./venv/bin/activate激活它。 现在,我们可以通过运行pip install slither-analyzer安装Slither 。注意, 请确保添加venv到你的.gitignore文件中。

大功告成!Slither现在可以使用了,我们继续安装其余工具。

2.2 MythX

回想一下,MythX不仅仅是一个扫描工具,因此设置将更加复杂。首先,你需要访问MythX网站 并单击“注册”来创建一个帐户。

现在,让我们生成API密钥,并将其保存在一个名为.env的文件中,其内容为 export MYTHX_API_KEY=yourApiKey。确保使用该确切名称,因为MythX会查找具有该名称的变量。 并且确保此文件不提交到Git存储库。

你会看到用于运行MythX的一些选项 - VSCode插件、Truffle插件、Remix插件和命令行客户端。 让我们使用安装命令行客户端:pip install mythx-cli

MythX的安装过程比Slither涉及更多,因为我们需要创建一个帐户并获取一个API密钥,但是 总体上来说还是很容易的。你很快就会看到为什么我们需要创建一个帐户。

2.3 Securify

理论上可以使用Python手动安装它,但是过程相当复杂,总之我没有能使用该方法让Securify运行。 因此我们将使用Docker安装此工具。

如果你从未使用过Docker,可以使用它创建或安装可以在任何计算机上运行的所谓容器,而与包含 所有依赖项的操作系统无关。如果你不知道如何使用Docker,那也没关系-只需按照以下安装说明进行操作, 以后就可以简单地运行指定的命令。

在项目根目录中,使用git clone https://github.com/eth-sri/securify2.git克隆存储库, 然后进入该目录中,并使用sudo docker build -t securify .来构建Docker容器。

完成后,我们就完成了所有工具的安装,可以开始运行某些扫描了。

3、运行安全扫描

好的,现在该玩有趣的东西了。让我们学习如何运行每个工具,然后我们将比较结果。 确保首先返回FakerDAO项目根目录。

3.1 Slither

如果我们要在项目中的每个合约上运行Slither,只需要执行slither .。如果只需要扫描一个合约文件, 可以运行slither path/to/contract.sol,在我们的示例中就是:slither contracts/Faker.sol

如果你使用的是FakerDAO示例,可能会注意到的第一件事是Slither不支持@风格的代码导入。 因此,你需要将import语句从import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol"; 更改为更明确的import "node_modules/@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";。

现在尝试再次运行该命令,你会看到结果已经输出到终端上!显示中包含了了各种安全检测器的结果, 可以在此处查看Slither支持的检测器的完整列表。

现在,你应该已经看到按严重程度进行颜色编码的结果,首先打印高严重性检测器,然后打印中严重性 和低严重性输出。

检测结果按检测器类型排序,因此在结果部分之后,会将看到一行开头为Reference:其中包含指向文档 的链接,可以访问该链接以便了解有关该特定检测器的更多信息。就是这样!你可以在下面看到输出示例。

通过阅读每个单独的消息和相应的文档后,你就可以确定需要对代码进行哪些更改。

Slither还附带了各种printer,可以输出不同的合约信息。例如,可以使用call-graph来打印调用图, 可以使用inheritance或inheritance-graph来打印继承关系,并且可以使用function-id轻松地获得功能ID。

printer不会直接告诉我们具体的安全问题,它只是会提供其他工具来帮助检查情况并确保代码结构 符合预期。

例如,我们可以使用slither contracts/Faker.sol — print call-graph获取合同的调用图。 这将为每个合约文件创建一个.dot文件,该文件可以显示一个调用图,如下所示:

还值得注意的是,Trail of Bits提供了一种名为Crytic的付费产品,该产品可以利用更多的检测器、 支持GitHub集成等。我没有使用过此工具,因此无法对其进行评论,但是就范围而言,它似乎类似于 MythX平台,从某种意义上说,它是一项全面的服务,而不仅仅是扫描工具。如果没有Crytic,你将 需要手动控制要保留并稍后引用的所有扫描结果。

3.2 MythX

MythX提供了不同的付费方案,并且每个方案都可以解锁不同的分析深度。 付费计划提供7天的免费试用期,因此我们将利用这一点来尝试三个不同的付费方案。

回想一下我们之前配置的环境变量,因此首先运行source .env进行设置。现在我们可以运行 mythx analyze以分析每个Solidity文件,但是在这里我们将使用mythx analyze contracts/Faker.sol 来分析单一文件。你还可以指定其他一些选项,参见这里。 第一次运行此过程可能会花费很多时间,因为会编译依赖关系,因此请耐心等待!随后的运行将更快。

与Slither一样,MythX也不支持@风格的代码导入,因此请确保更改导入路径以显式列出 node_modules文件夹。完成后,你将看到类似以下的输出。请注意,默认情况下,此命令将在 快速扫描模式下运行MythX - 后面我们还会测试标准扫描模式和深度扫描模式。

请注意其中的警告信息,意思是免费版本不会检测到所有的漏洞类型。但是,我没有找到一个页面来说明 每种付费方案可以检测的漏洞列表。尽管从文档中还不清楚,但我的理解是MythX层按如下方式 提供了对功能的访问,

  • 免费方案 → 仅快速扫描
  • 开发人员方案 → 快速扫描+标准扫描
  • 专业方案 → 快速扫描+标准扫描+深度扫描

升级到Developer版本并重新运行后,你会看到警告已删除,并且由于它是相同的扫描类型,因此未发现 其他漏洞。

现在让我们运行标准扫描和深度扫描。这些模式分别需要多达5、30和90分钟。要运行标准扫描, 请使用--mode标志,例如mythx analyze contracts/Faker.sol --mode standard

以下是标准扫描和深度扫描的结果:

对于我们在这里使用的FakerDAO合同,快速扫描几乎是即时的,标准扫描大约需要20分钟, 深度扫描大约需要45分钟。我们可以看到,越来越多的层级确实发现了更多潜在的漏洞。在下一节中, 我们将更详细地比较这些结果。

回想一下,MythX不仅仅是一个扫描工具。在上图中,你会注意到一个包含报告的仪表板的URL。 你创建的API密钥已链接到MythX帐户,因此可以在任何地方登录并获取所有分析的历史记录。 这包括运行的日期和时间,测试的源文件以及发现的漏洞。以下是你可以在信息中心中找到的三个 不同页面,这些页面是我们上面运行的标准扫描所显示的。

查看分析:

给定扫描的高级概述:

给定扫描的详细信息页面:

3.3 Securify

先在看最后一个工具。Securify当前仅支持单文件合约,这意味着不支持使用import。因此, 要使用Securify,你必须使用完整的Solidity文件手动替换导入。有一些flat工具可以完成此任务, 例如solpptruffle-flattenersolidity-flattener等,Slither附带也有。

完成此操作后,你可以使用sudo docker run -it -v <full/path/to/contracts>:/share securify /share/<contract.sol>进行分析。 在我们的例子中,由于我们只想运行Faker.sol合同,因此我们将使用sudo docker run -it -v $(pwd)/contracts:/share securify /share/Faker.sol

如果你不熟悉Docker,则此命令的功能概述如下:

  • sudo docker run :以管理员身份运行Docker容器
  • -it :作为交互过程运行容器(这使你可以在Docker容器内的终端中输入命令)
  • -v $(pwd)/contracts:/share:与Docker容器的目录共享contracts由完整文件路径指定的本地目录。Securify工具位于容器中,因此容器可以读取我们的本地合同文件。
  • securify /share/Faker.sol:在Docker容器中运行以执行分析的命令

现在,我们等待分析运行,你将看到如下图所示的内容。此处的输出有些混乱,因为颜色似乎与严重性 不符 - 请注意黄色消息是中等和高位,而红色消息是信息,中,高和严重。此外,请注意,前两个消息 都是中等级别的Missing input validation,但是它们以不同的颜色显示。在此处阅读输出时请小心, 以免误解任何内容。

4、安全扫描结果分析

在获得结果之前,我们应该注意,本文远非全面,还有很多可以扩展的内容,例如:

  • 这些工具并不完全是公平的1:1比较。例如,MythX将运行静态分析、符号分析器和模糊器。 另一方面,Slither只是一个静态分析工具,而相关的符号分析器和模糊器则分别称为Manticore和Echidna的工具。
  • 我们没有深入研究Slither的printer,也没有介绍其API。
  • 我们没有涉及Trail of Bits提供的其他工具,例如其模糊测试器Echidna或符号分析器Manticore。
  • 我们没有查看每种工具提供的全套服务,例如CI / CD集成,GitHub集成或支持。
  • 我们没有考虑产品的成本。

好的,现在我们可以比较结果了!

我们将使用SWC注册表 - 智能合约缺陷分类注册表进行比较。 其中包含潜在的智能合约漏洞的列表,以及每一个的解释、参考和测试用例。

下表列出了每次扫描的结果。有关此表的一些注意事项:

  • 为了清楚起见,隐藏了任何工具都找不到的SWC漏洞
  • 并非所有工具都直接映射到此注册表,因此括号中会解释该工具所描述的特定问题。
  • 带星号的SWC ID是我添加的虚构ID,因为在SWC注册表中找不到与该工具输出匹配的匹配项。 这些“新” SWC ID的名称是从工具输出中提取的。
  • 我没有根据合约手动验证每个报告的有效性和准确性,因此请审慎查看这张表。
  • 不要以为计数最高的那个是最好的。

不再废话,上结果!

那么我们可以从这里得到什么启示呢?下面是我的一些想法:

  • 没有任何安全工具足以替代审计!
  • 没有哪个安全工具能够解决所有问题:只有Slither提到了严格的不等式, 只有MythX提到了时间戳依赖性,只有Securify提到了输入清理和未初始化的状态变量。
  • 即使工具捕获到相同的漏洞类别,它们可能捕获到的是不同的实例。

还值得注意的是,Securify的输出特别奇怪,并且包含一些误报。除了上面提到的令人困惑的颜色编码外, 某些输出还没有意义,也没有提供URL来查找更多信息。例如,这个Uninitialized State Variable 消息无法检测到那些已在构造函数中初始化的变量。同样,也不清楚Unrestricted write to storage 担心的是什么,以及寻求何种检查作为补救措施。

像这样的安全扫描工具肯定在合约开发过程中占有一席之地,应始终使用。使用多种工具而不是仅 依靠一种工具似乎是捕获潜在错误的最佳方法,但是没有工具或工具组合可以代替完整的审计。

如果你必须在未经审核的情况下部署到主网,请给你的网站和代码添加警告,并考虑限制合约所能 容纳的最大金额。

祝好运!


原文链接:Ethereum Security Analysis Tools: An Introduction and Comparison

汇智网翻译整理,转载请标明出处