前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >智能合约:访问控制缺陷

智能合约:访问控制缺陷

作者头像
yichen
发布2020-05-18 13:45:09
4760
发布2020-05-18 13:45:09
举报

访问控制缺陷是因为编写 solidity 智能合约的时候,对于某些判断的定义不严谨或者笔误,导致的某些敏感功能的访问验证被绕过问题。攻击者可以恶意使用某些敏感功能

漏洞分析

先看一段代码片段

代码语言:txt
复制
//函数修改器用于检验是否允许转移Token
modifier isTokenTransfer{
  //if token transfer is not allow
  if(!tokenTransfer){
    revert();
  }
  _;
}
//函数修改器用于检验是否来自钱包本身
modifier onlyFromWallet{
  require(msg.sender != walletAddress);
  _;
}
contructor(uint initial_balance,address wallet){
  require(wallet !=0);
  require(initial_balance !=0);
  _balances[msg.sender]==initial_balance;
  _supply = initial_balance;
  walletAddress = wallet;
}
function transfer(address to, uint value) isTokenTransfer checkLock returns (bool success){
  require(_balances[msg.sender] >= value);
  _balances[msg.sender] = _balances[msg.sender].sub(value);
  _balances[to] = _balances[to].add(value);
  Transfer(msg.sender,to,value);
  return true;
}
function enableTokenTransfer() external onlyFromWallet{
  tokenTransfer = true;
  TokenTransfer();
}
function disableTokenTransfer() external onlyFromWallet{
  tokenTransfer = false;
  TokenTransfer();
}

在代码中的 transfer 函数,除了转账功能还增加了两个修饰符 isTokenTransfer 和 checkLock,我们主要讨论 isTokenTransfer 函数

代码语言:txt
复制
modifier isTokenTransfer{
  if(!tokenTransfer){
    revert();
  }
  _;
}

当 tokenTransfer 变量为 false 时,被 isTokenTransfer 修饰的函数是无法正常执行的,在 disableTokenTransfer 函数可以把这个变量改成 false,disableTokenTransfer 有一个修饰符是 onlyFromWallet 字面意思上看应该是只能合约本身去调用的

代码语言:txt
复制
function disableTokenTransfer() external onlyFromWallet{
  tokenTransfer = false;
  TokenTransfer();
}

onlyFromWallet 函数定义在这里

代码语言:txt
复制
modifier onlyFromWallet{
  require(msg.sender != walletAddress);
  _;
}

加这个本意是只能合约本身去调用的,但是这里 != 的条件判断下来的话就是 如果调用者不是合约本身反而是通过的了

代码调试

https://cn.etherscan.com/address/0xb5a5f22694352c15b00323844ad545abb2b11028#code

去这里复制一下代码

用默认账户选择 IceToken 合约,在 wallet 中填上默认账户的地址,在 initial_balance 中填上 100,然后部署

切换到第二个账户

0x14723a09acff6d2a60dcdf7aa4aff308fddc160c

先点击 enableTokenTransfer,然后使用 reansfer() 向自己转移 0 个 Token,测试一下是否

然后我们使用 disableTokenTransfer 让转账不可用,注意,我们现在并不是合约的部署者,理论上说是不能修改这样的东西的,否则随便一个人就能让你的用户没法转帐?不能接受吧

他的问题在这里

代码语言:txt
复制
modifier onlyFromWallet {
       require(msg.sender != walletAddress);
       _;
   }

!= 应该是 == 的,这样结果反而是除合约所有者之外的所有人都可以更改了,实际上韩国有个区块链项目 ICON(ICX) 的智能合约就出现过这个问题

漏洞防范

必须对由于表征权限的变量和表示进行严格的控制,即这些敏感变量也应通过函数修饰符进行权限控制,从而保证权限闭环

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陈冠男的游戏人生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
区块链
云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档