拘于小节的调用权限——函数调用权限漏洞

针对区块链安全问题,成都链安科技团队每一周都将出智能合约安全漏洞解析连载,希望能帮助程序员写出更加安全牢固的合约,防患于未然。

引子:天下难事,必作于易,天下大事,必作于细 —— 《道德经·第六十三章》

本期话题

可见修饰字斟句酌,函数调用约法三章

自由与限制,两个矛盾又相辅相成的状态。有人言,没有限制的自由不是真正的自由。正如《海上钢琴师》的台词:“钢琴有低音的开头,也有高音的结束,八十八个琴键是有限的,却可挥洒出无限的动人音符,我喜欢这说法,这也是我生存的方式…陆地对我而言就是一艘大船,这世界上有数以千计的街道,而你要如何走到尽头,你要如何选择一个妻子,一栋房子,一幅风景,甚至何种方式死去?这些在我面前就像无穷多琴键的钢琴,但我却一个音符也弹不出来…”当自由挣脱限制的束缚,会让人感到恐惧和迷茫。

自由和限制的关系,也正是科技发展和安全的关系。合约安全的精髓就是限制及控制理念,精确的附加限制条件是防御安全漏洞的有效手段。在函数调用权限的问题上,正确添加函数说明符或者修饰符来控制调用的范围和权限,是协助预防攻击者调用重要和敏感的函数的“保护伞”。

基础知识

函数可见性说明符(Function Visibility Specifiers)和函数修饰符(Function Modifiers)都可以归纳为修饰函数的成分,为了区分我们分开讲解两个概念:

1. 什么是函数可见性说明符(Function Visibility Specifiers)?

Solidity有两种函数调用方式,一种是内部调用,不会创建一个EVM调用(也叫做消息调用),另一种则是外部调用,会创建EVM调用(会发起消息调用)。Solidity对函数和状态变量提供了四种可见性。分别是external,public,internal,private。其中函数默认是public。

external· 声明为external的函数可以从其它合约或通过Transaction进行调用,所以声明为external的函数是合约对外接口的一部分。

· 不能直接进行内部调用。

public· 函数默认声明为public。

· public的函数既允许内部调用,也允许外部调用。

· public的函数由于被外部合约访问,是合约对外接口的一部分。

internal· 在当前的合约或继承的合约中,只允许内部调用。

· 即使声明为private,仍能被所有人查看到里面的数据。访问权限只是阻止了其它合约访问函数或修改数据。

由于变量的可见性说明符与函数类似,这个特殊情况也可以造成变量的外部读取,我们在第九期重点解析了这个问题,请移步:https://mp.weixin.qq.com/s/hP_Cc2CiqFyrnYqK9W_3nQ

2. 什么是函数修饰符(Function Modifiers)

修饰符可以用来轻松改变函数的行为,比如在执行的函数之前自动检查条件。他们可继承合约的属性,也可被派生的合约重写。除了官方的一些修饰符,例如,view(函数不会更改和保存任何数据);pure(函数既不会往区块链写数据,也不从区块链读取数据)之外,我们还有自定义修饰符,用来自定义其对函数的约束逻辑。这些函数可以同时作用于一个函数,例如:

function test() external view oneModifier anotherModifier

限制缺失,函数迷失

从上面的知识我们可以总结,可见性说明符和函数修饰符直接关系到函数可以被谁调用。如果重要和敏感函数缺少相关的修饰成分,就可能沦为攻击者不劳而获的工具。如同各种电影动漫中神秘的力量需要被封印一样,不能正确限制这种力量,势必带来无法挽回的后果。

在基础知识中我们提到,函数默认的可见性为public,允许用户从外

函数调用权限漏洞

我们按照可见性说明符和修饰符将漏洞分为两类:

1. 可见性权限漏洞

部调用它们。可见性说明符的不正确使用可能会导致智能合约中的资金流失:

在基础知识中我们提到,函数默认的可见性为public,允许用户从外

错误代码示例

函数的默认可见性是public,意味着任何人都可以操作上面的_transfer函数,实现不需要授权就可以转走他人的代币。

2. 调用权限不符

部分敏感函数需要onlyOwner权限,如果该函数忘记添加onlyOwner函数修饰器,那么任何人都可以操作该函数,破坏合约执行逻辑。

错误代码示例

setOwner() 函数的作用是修改 owner,通常情况下该函数只有当前 owner 可以调用。 但问题代码中,任何人都可以调用 setOwner() 函数,这就导致了任何人都可以修改合约的 owner。 该问题本质上是函数调用权限不符的漏洞。

漏洞修复

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181102A0U5VB00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券