Solidity安全之默认可见性(Visibility)

曲速未来安全区
曲速未来安全区 机构得得号

Aug 11, 2018 专注于为读者提供区块链安全领域最新讯息

摘要: Soildity作为编写智能合约的语言,已经被广泛的应用。但同时,开发者和用户也得到了惨痛的教训,智能合约的安全问题层出不穷。因此,我们总结了一些常见的Solidity安全问题。前车之鉴,后车之师,希望后来者能有所警惕。

Soildity作为编写智能合约的语言,已经被广泛的应用。但同时,开发者和用户也得到了惨痛的教训,智能合约的安全问题层出不穷。因此,我们总结了一些常见的Solidity安全问题。前车之鉴,后车之师,希望后来者能有所警惕。
默认可见性(Visibility)

Solidity有两种函数调用方式,一种是内部调用,不会创建一个EVM调用(也叫做消息调用),另一种则是外部调用,会创建EVM调用(会发起消息调用)。其中的函数具有可见性说明符,它们会指定我们可以如何调用函数。可见性决定一个函数是否可以由用户或其他派生契约在外部调用、只允许内部调用或只允许外部调用。Solidity对函数和状态变量提供了四种可见性。分别是external,public,internal,private。为允许用户从外部调用函数,其中函数默认可见性默认为public。而本文将介绍的是可见性说明符的不正确使用会导致智能合约中的一些资金流失的问题。

代码分析

函数的可见性默认是 public。因此,不指定任何可见性的函数就可以由用户在外部调用。当开发人员错误地忽略应该是私有的功能(或只能在合约本身内调用)的可见性说明符时,问题就出现了。

让我们看一个简单的例子。

这个简单的合约被设计为充当赏金猜测游戏的地址。要赢得该合约的余额,用户必须生成一个以太坊地址,其最后 8 个十六进制字符为0。一旦获得,他们可以调用 WithdrawWinnings() 函数来获得赏金。不幸的是,这些功能的可见性没有得到指定。特别是,因为_sendWinnings() 函数的可见性是 public,任何地址都可以调用该函数来窃取赏金。

相关事件

我们昨天在前一篇介绍Delegatecall函数滥用问题中引用了Parity钱包被黑事件,默认可见性也是攻击者在这次事件中利用的漏洞之一。接下来我们详细的分析攻击者的利用过程:

先看看Parity钱包的合约,有两个,其一是库合约,第二是钱包合约。

库合约包含初始化钱包的代码,如以下代码片段所示

在合约中,initWallet() 与initMultiowned()两个函数的可见性都默认为 public 。钱包构造函数会调用 initWallet() 函数,并设置多签名钱包的所有者,如 initMultiowned() 函数中所示。由于这些函数意外地设置为 public,攻击者可以在部署的合约上调用这些功能,并将所有权重置为攻击者地址。作为主人,袭击者随后取走钱包中所有的 Ether,损失高达 3100 万美元。

区块链安全公司WF曲速未来 观点:

指定合约中所有功能的可见性、即便这些函数的可见性本就有意设计成 public,这是一种很好的做法。最近版本的 Solidity 将在编译过程中为没有明确设置可见性的函数显示警告,以鼓励这种做法。所以人们在编写智能合约时应注意函数可见性说明符的正确使用。

注: 本文内容由区块链安全公司WF曲速未来(WarpFuture.com)  编译,转载请注明来自WF曲速区。WF是交易所与超级节点的安全技术提供商,为区块链交易所提供媲美某猫双十一级别的账户安全与交易安全对抗云引擎,现交易所每日安全攻防调用量达亿级。

链得得仅提供相关信息展示,不构成任何投资建议
本文系作者 曲速未来安全区 授权链得得发表,并经链得得编辑,转载请注明出处、作者和本文链接

更多精彩内容,关注链得得微信号(ID:ChainDD),或者下载链得得App

分享到:

相关推荐

    评论(0

    Oh! no

    您是否确认要删除该条评论吗?

    分享到微信