节省费用,丢失代币

上个月,安东·布科夫(Anton Bukov)推出了Feeless库,这是一种非常有趣的以令牌支付以太坊交易费的方法:https://medium.com/bitclave/do-not-pay-transaction-fees-in-ethereum-21a9dccaaf63

虽然我建议阅读Anton的文章,但我将在此处提供我的个人摘要:代币持有人不会发送会产生交易费用的交易,而是会产生一个特定的签名,允许其他人执行交易。 其他人可以发送交易并支付费用,从而有可能收到代币。 交易结果应与常规执行相同。

正如安东(Anton)和罗兰·科夫勒(Roland Kofler)征求反馈一样,我们很高兴就安全性提出我们的看法。 与Anton一样,我们还将在演示中使用令牌,但是由于稍后将变得清楚的原因,它是ERC827令牌。

我们认为,库的设计可能会导致无法预料的攻击 ,这在原始实现中是不可能的。 因此,我们建议不要在当前状态下或仅在执行合格的安全审核后使用Feeless

攻击

我们的示例类似于Anton的原始示例。 通过使用该库,我们可以approveAndCall修改approveAndCall函数,方法是添加msg.sender修饰符并将msg.sender替换为msgSender

免费的ERC827令牌的令牌代码。

正如我们在上面看到的那样,ERC827令牌将在第28行通知令牌接收者有关转移的信息。攻击者可以使用此功能对Feeless的实现进行一次重入攻击 ,否则该方法将不可行。 为什么? 因为添加到相关功能的无费用修饰符的实现不受防止重入的保护,所以:

库中实现的无费用修饰符。

正如我们在上面看到的, msgSender不会重置msgSender 。 因此,在进行ERC827令牌传输的情况下,接收方可以重新输入approveAndCall函数,并以发送方的名义执行更高级别的令牌批准。

简而言之,接收方可以从发送方窃取其他令牌。

在我们的GitHub存储库中,我们提供了完整示例的代码。 您可以通过运行测试用例来执行攻击。 测试案例使用以下攻击者代码,这是执行重新进入所必需的:

批准自己100个令牌的攻击者代码。

最后,请注意Feeless或相关方法的设计或实现可能存在其他问题。 我们尚未执行全面审核。 如果本文引起您对我们服务的兴趣,请随时通过https://chainsecurity.com访问我们。

我们基于研究的解决方案可以自动识别这些安全问题。 即将发布的Securify完整版本将启用这些检查。 敬请关注。