基于区块链的智能合同II——已知的漏洞和陷阱

在这个系列的前一部分,我们分析了与部署在公开区块链上的自动化执行智能合同有关的风险。我们也介绍了一些获得高关注度的智能合同的例子,造成了大笔钱的损失,并且改变了我们看待区块链上的商业活动的方式。

在这一部分我们会回顾一些已知的问题和漏洞。

私钥泄露

使用不安全的私钥实际上是用户错误的一个常见例子,甚至超过漏洞。然而,我们从来不提这一点,因为它经常发生,而且某些玩家专门从不安全的地址偷基金。

最常见的情况是在产品中使用建设地址(例如用在测试工具中的,如Ganache / TestPRC)。这些地址是由公众所知的私钥生成的。一些用户甚至在不知不觉中将这些密钥导入钱包软件,通过使用私钥生成中原始种子。

攻击者检测这些地址,任何转移到这个在主以太币网络地址的金钱都会立即消失(在两个数据块中)。

这项非常有利可图“清扫”活动已经调查了这项有趣的研究,并且发现一个清扫人员账户已经设法积累了2300万美元的资金。

可重入性和竞争条件

如果一个功能模块在完成前调用了很多次,那么可重入性漏洞包含意想不到的行为。

让我们来看看下面这个函数,这个函数可以用于从一个合同中撤回访问者的总余额

call.value()函数可以导致合同外部的代码执行。我们可以把访问者假设成一个数字加密货币钱包软件。

如果这个访问者是另一个合同,这就意味着这个合同的回退函数被执行了。执行回退函数的目的就是收到资金。

一个流氓合同,在余额设置为0之前,实现了一个叫做payout()的回调函数进行再次递归,从而获得比现在更多的资金。

这个问题的解决方案是使用可代替的函数sent()或者transfer()。防止递归调用,通过转发足够的基本的簿记和一些调用payout()的尝试将会失败。另外(或者是再者),操作的顺序可能被替代,例如在进行金钱兑换之前把余额设为0。

在第一部分中提及的DAO攻击就用到这个漏洞的一个变种。

溢出

余额通常由无符号整数代替,固态中通常有256比特数字。当无符号整数下溢或溢出时,它们的价值立马就改变了。现在我们来看一个常见的下溢的例子(可读性缩短):

0×0003

— 0×0004

———————-

0xFFFF

这里很容易就会发现一个问题,减去一个比减数大1的数会导致下溢,结果就会得到一个大数。

也请注意,由于四舍五入的误差,整数计算的除法会非常复杂。

解决方法是不断地检查代码中的下溢或上溢。这里有安全库协助检查,例如SafeMath 或者OpenZeepelin。

交易定单假设

贸易进入未经证实的交易池并按照某种规律包含在矿工的数据块中,这种规律取决于矿工的交易选择标准,这很可能是由于一些算法意图从交易费中实现利益最大化,也可能是其他的什么情况。

因此,包含的交易的顺序和其它他们生成顺序完全不同。因此,合同代码不能在贸易规则里创造任何假设。

除了在执行合同过程中没有预料到的结果,这里还可能有一个攻击向量,由于交易是可见的,而且这个交易是可以预见的。这可能是交易中的一个问题,也就是延迟交易可能会被流氓矿工用于个人利益。事实上,在交易之前就需要意识到某些的交易,既然可以被矿工利用,也可以被其他的任何人利用。通过支付一个较高的燃气费交易可以被“超越”,从而鼓励矿工迅速将其包含在内。

时间依赖性

在区块链中,时间戳是由矿工生成的。因此,没有合同需要为了特定的操作而依赖于数据块的时间戳,例如把它用作生成随机数的种子。Consensys在他们的规则中给出一个12分钟的 指南,这表明使用数据块是安全的。时间戳,如果你的时间依赖代码能够处理12分钟时间变化。

总结

迄今为止,我们看了很多获得了高关注度的基于区块链的智能合同攻击的例子,我们也讨论了一些已经发现的常见的漏洞。在下一篇文章中,我们将会介绍一些更复杂的攻击,这些攻击依赖于区块链和特定操作的工作方式。

*参考来源:security of blockchain-based smart contracts II-Konwn Vulnerabilities and Pitfalls,本文由丁牛网安实验室小编EVA编辑整理,如需转载请标明出处。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180328G0LGRZ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券