当前位置:首页 > 比特币新闻 > 正文

经常让人忽视的漏洞—以太坊gas的三大安全隐患

来源: 互联网时间:2019-01-26 07:30:01

发送到以太坊区块链的每笔交易都需要通过大量的计算工作来处理。Gas是衡量和支付处理工作的方式。用户倾向于将gas视为一种令人困惑的烦恼,开发人员往往从优化成本的方面看待gas。作为一名优秀合约审计员,笔者经常将gas视为潜在的攻击载体。在这篇文章中,笔者将研究gas导致安全漏洞的三种方式。

38178155242_088439ccc4_b

发送交易的人是支付gas的人

关于交易的一个基本事实是,它们是由交易发送者——签署交易的帐户支付交易费用的。

如果出现以下情况,可能导致攻击载体的产生:

1.攻击者可以让你发送一个交易,并且
2.它们可能导致该交易消耗大量gas。

满足第一个条件并不难。如果我在一个中心化交易所(例如Coinbase)拥有一个账户,我可以指示交易所将资金转移到我选择的账户。典型的实施步骤就包括交易所从其中一个账户发送交易。由于是交易所发送交易,他们需要支付gas。

对于智能合约开发人员来说,满足第二个条件很容易。智能合约可以运行任意代码以响应传入的交易。以下智能合约在收到ETH转账时会消耗很多gas:

WX20181227-151540@2x

交易的发送者指定了将消耗gas的上限,称为gas限制。此限制通常通过模拟交易来自动确定。如果交易所这样做,他们很容易被欺骗,从而消耗大量gas。

上面的代码无意义地消耗了大量gas,很明显这些gas可以用于更有效的使用。也许攻击者的合约可以用这些gas进行一些有价值的计算。正如Level K最近观察到的那样,多余gas的一个很好的用途就是用它来发行GasTokens,可以退回,也可以出售。

降低风险

为了保护自己免受此类攻击,请确保始终为你的交易设置合理的gas限制

将交易填充进区块的人可以发起拒绝服务攻击

由于以太坊的计算资源是有限的,因此单个区块中可以使用多少gas也是有限的。这被称为区块gas限制。矿工试图将交易打包进一个区块,以尽可能接近该gas限制,因为gas费用是支付给矿工的。

在撰写本文时,以太坊主网络的区块gas限制约为8,000,000。消耗更多gas的交易根本无法挖掘。

这可能成为一种拒绝服务攻击载体——攻击者致使智能合约无法运行的一种方式。以下是易受攻击的智能合约示例:

WX20181227-151658@2x

如果deposit数组足够长,则无法再调用withdrawAll(),因为这样的交易不适合区块。攻击者可以通过重复调用deposit()直到达到正确的数组长度来轻松导致此情况的发生。这将锁定合约中所有现有的ETH。

通过完全用交易填充你的交易区块,也可以对整个区块链发起拒绝服务攻击。只要这些交易指定了足够的gas,理性的矿工就会将攻击者的交易打包进区块。

降低风险

智能合约审计人员一看到for循环就会感到紧张。尽量避免使用它们,除非它们受到恒定迭代次数(而且,次数少)的限制。

区块填充攻击的成本很高,因此为了减轻这一风险,在设计合约时,尽量减小固定期限的财务影响。例如,拍卖通常有接受出价的截止日期,因此区块填充攻击可能会阻止人们出价。确保在这样的系统中拍卖的商品没有足够的价值,以至于区块填充攻击在经济上具有可行性

转发交易的人是支付gas的人

作为第一种漏洞的workaround(虽不能根本解决,但能避开问题的替代方法),笔者最近看到很多关于所谓的“元交易(meta transaction)”的讨论。元交易很像交易,但能够通过第三方进行转发(relay)。第三方中继器是实际发送交易的账户,因此它支付gas。

这是通过签名和代理合约完成的。用户签署他们的元交易并将其广播给全世界。任何看到元交易的人都可以将其转发给代理合约。只要消息包含有效签名,代理协定就会执行指定的调用。通常用户需要给中继器支付费用(例如用代币支付)以支付中继器所需花费的费用。

在这种方案中,中继器具有不寻常的攻击载体。作为交易发送者,他们可以决定他们提供多少gas。如果提供太少的gas,它们可能导致调用失败。如果他们有特殊的动机这样做,这将会是一个问题,如下面的合约:

WX20181227-160435@2x

随机数(nonce)用于防止重放攻击,但请注意,nonce仅在调用成功时递增。一个恶意的中继器可以通过操纵gas限制来使调用反复失败。每次中继器调用执行时,无论使用了多少gas,它们都会得到报酬。

降低风险

一种解决方案是不管调用的成功或失败都增加nonce,但会导致拒绝服务攻击载体的产生。每次用户广播他们的元交易时,恶意中继器都可以获取该元交易并导致它像以前一样失败。现在nonce已经增加,用户需要签署新的元交易,然后重复该过程。

如果调用失败,另一个诱人的解决方案是回滚交易,但这意味着当调用因正当原因失败时,无法补偿中继器。

最好的解决方案是直接解决根本问题,即中继器被允许指定交易的gas限制。要将其锁定,请务必在签名消息中包含gas限制,并检查代理合约中是否遵守了该限制。这是Status的中继代理所采用的方法。

Christian Lundqvist的“简单多重签名钱包”主要通过允许用户将交易发件人指定为其签名消息的一部分来缓解此问题。这意味着恶意中继器无法在一开始就参与交易。

总结

如果不对gas问题进行适当的关注,可能会导致严重的智能合约漏洞。在审查代码时,这些漏洞通常是不明显的,但它们确实会造成很大的麻烦。

免责声明:

1.本文内容综合整理自互联网,观点仅代表作者本人,不代表本站立场。

2.资讯内容不构成投资建议,投资者应独立决策并自行承担风险。

你可能感兴趣