ERC20代币部分合约存在不一致性检查漏洞
摘要: ERC20 发行的代币安全性是无法保障的,对于广大用户来说,除了自身加强自我安全意识意外,也要有一双火眼金睛
一、前言
近日,我们发现ERC20代币部分合约中的transferFrom中存在不一致性检查漏洞(check effect inconsistency)。
什么是ERC20代币?
简单的说,任何 ERC20 代币都能立即兼容以太坊钱包(几乎所有支持以太币的钱包,包括Jaxx、MEW、imToken等,也支持erc-20的代币),这就意味着,在很多情况下,这些代币都是可以立即进行交易的。
ERC20 让以太坊区块链上的其他智能合约和去中心化应用之间无缝交互。因此ERC20协议是目前数字货币交易体系中较为主流的一种协议体系。但是该协议也存在不完善的地方。
ERC20规定了代币名称、代号、发行量、转账等一系列常用的代码规范,只要按照这个规范来设计的代币智能合约,就能在绝大多数以太坊钱包上使用。
ERC20标准使用起来也非常方便,几十行代码即可实现完整功能的代币。所以熟练的程序员用15分钟建立一个ERC20代币并不是困难的事。
但是,发币容易,守币难。经常被发现有漏洞,导致损失惨重。
4月22日,有黑客利用以太坊 ERC20 智能合约中 BatchOverFlow 漏洞中数据溢出的漏洞攻击了美链 BEC 的智能合约,从中盗取产出57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,0 亿个BEC ,并大规模的向市场上抛售。
4月25日,代币SMT发现与被爆出的BEC代币类似的安全漏洞,可以利用溢出攻击获得大量代币。
这些数字多到数不清…
然而出问题的远远不止这些。漏洞事件集中爆发,不同的项目存在相同的漏洞,这也让业内一直存在的“代码互抄”现象,再次成为网络上关注区块链技术的投资者们讨论的话题。
回顾上次LightCoin合约非一致性检查漏洞。
简述一下LightCoin:
LIGHT (光链) 是世界上第一个双层区块链(父链与子链)。其中,LIGHT 父链与传统的公链类似,有且仅有一个,保证记录完整、透明、不可被篡改或销毁。LIGHT子链可以是多个且相互独立存在,基于PoM validation方式,结合In-Memory数据库缓存,有效提高缓存环节吞吐量,QPS可达10万以上,实现性能大幅提高。
漏洞详情:
合约类型:ERC20;
漏洞函数:transferFrom。
漏洞类型:非一致性检查;
漏洞危害:可导致绕过授权额度检查,转出超出授权额度代币至任意以太坊账户。
代码分析:
可以看出代码55行在检查授权转账额度是没有问题的,但是在58行减掉已转出的授权额度时,错误的写成了allowed[_from][_to] -= _value。该行代码导致在授权转账完成后,限额依然不变,在下一次操作授权转账时,依然可以继续按照原本限额转出代币。该漏洞属于一个逻辑漏洞,由于校验的条件和操作的条件不一致,导致后续绕过校验。
该漏洞逻辑如图所示:
经过对此漏洞类型进行了深入的分析,发现了不仅存在 `allowed[_from][msg.sender]` 这一语句的检查不一致,还存在 `balances[msg.sender]` 语句的检查不一致漏洞。
二、漏洞原理
1、allowed不一致性检查漏洞
如上面代码所示:
这一条的条件检测与
这一语句的操作不相符,导致设置转账额度权限后,攻击者能够持续转账,直到转完所有余额。
2、balances 不一致性检查漏洞
如上图的代码所示,上面一句的条件检测与下面一句的语句操作不相符,攻击者能够通过溢出,让`_from`账户余额获得极大的token 数量。
同时,有一些合约中使用了 safeMath 安全方法进行计算 `balances[_from] = balances[_from].sub(_value);`,所以暂时没有溢出问题,但是条件检查部分是冗余的。
修复方案如下:
1.使用safeMath方法进行计算;
2.使用`balances[_from] >= _value`作为条件判断而非`balances[msg.sender]`
3.检查`allowed[_from][msg.sender]`并对`allowed[_from][msg.sender]`进行操作不要与`allowed[_from][_to]`混用。
ERC20 发行的代币安全性是无法保障的,所以,对于广大用户来说,除了自身加强自我安全意识意外,也要有一双火眼金睛,来分辨出哪些数字货币是安全的,值得投资的,哪些是有风险的。只有这样,才能让自己的资产受到最小的损失。
评论(0)
Oh! no
您是否确认要删除该条评论吗?