以太坊-智能合约审计——权限隐患

以太坊-智能合约审计——权限隐患


一、智能合约中的权限

  • 合约拥有者(owner):执行合约中所有函数
  • 普通用户:只能调用约定范围内的函数

二、Solidity中函数权限

  • Public:函数可以被合约内部函数、继承合约、外部合约调用

  • Private:只能被合约内部函数调用

  • Internal:可以被合约内部函数以及继承合约调用

  • External:只能外部合约调用

    注意:函数如果不限定,Solidity语言会默认设置函数为Public权限,也就是任何合约可以调用!

    HCTF的ez2win题目就是利用这个点来破解得到flag


三、构造函数权限问题

  • Solidity编写合约和面向对象编程语言非常相似,可以用构造函数(constructor)来初始化合约对象
  • 类似C++等语言,Solidity中构造函数是方法名和合约名字相同的函数,创建合约时会调用构造函数对状态变量进行数据初始化操作
  • 构造函数可用的函数类型为public或internal
  • 如果构造函数带参数,必须要放在合约下的第一个函数
pragma solidity ^0.4.16

contract Function{
    Function Function() public{
        //构造函数内容`
    }
}

​ 0.4.22版本后,solidity编译器引入了constructor关键字。以替代低版本的将合约名作为构造函数名的语法,避免程序员容易出现的编码错误。使用旧写法会出现 warning 信息。

pragma solidity ^0.4.22

contract Function{
    constructor() public{


    //初始化操作
}
Function test(){

    //其他函数功能性代码
}
}
安全问题

​ 构造函数之所以区别于普通函数,是因为构造函数它主要用户初始化整个合约对象,而且不能被任意用户所调用,所以一旦构造函数可以被任意用户调用时,调用者就可以获得初始化合约的权限,带来安全隐患。

1.构造名与合约名不相同

​ 编译器0.4.22之前:

​ 构造函数的函数名默认是和合约名一致的,如果智能合约的开发者在开发过程中出现”构造函数名与合约名不一致”的现象(大小写、多加了一个s等情况),那么构造函数将不再是“构造函数”,而变为一个任意用户可以调用的普通函数,任意用户可以通过调用该函数实现对合约的初始化操作。

2.constructor函数不规范

​ 在编译器0.4.22之后:

​ 使用了constructor来替代原先的“构造函数名与合约名必须一致”的代码编写规范,但是一些合约开发者在开发工程中往往还是会出现各种错误,例如:在constructor前面加function,或者加了function然后开头的C写成了大写,即“function Constructor(){}”,这样便使得构造函数变成了公有函数,可被人任意调用。


四、普通函数权限问题

​ 对于一些普通函数,我们一般会使用一些修饰器来进行修饰,同时有时候也会使用public、private、internal、external来进行修饰。一些合约开发者留下“后门”,owner可以销毁任意用户的任意代币。那么如果owner被他人控制呢?

发表评论

电子邮件地址不会被公开。 必填项已用*标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部