6月24号(2018),安比(SECBIT)实验室 与 轻信科技 发现了不少 ERC827 合约实现存在类ATN Token 漏洞。黑客可以利用该漏洞,以合约的身份调用任意合约地址上的任意函数。其中大部分问题合约参考了 OpenZeppelin 官方提供的 ERC827 模板,安比(SECBIT)实验室小伙伴 p0n1 随即向 OpenZeppelin 项目报告了该问题。Zeppelin 及时移除了 GitHub 官方仓库中带有安全隐患的 ERC827 合约模板。
安比(SECBIT)实验室正在积极参与以太坊社区的临时工作小组,寻求有效的安全修订方案。为了安全起见,暂时请不要再使用 ERC827 相关代码。
特别提醒
- 新项目方:进行智能合约开发时,目前请不要使用 ERC827 代码模版
- DApp开发团队:DEX 和 DApp 开发者目前请勿与使用 ERC827 Token 的合约进行交互对接;已采用 ERC827 提案的 DApp 开发团队请进行自查,评估所受影响
- 用户与交易所:请对相关项目保持密切关注
目前有活跃交易的 ERC827 Token 有:
Name | Symbol | 交易所 |
---|---|---|
BOB Token | (BOB) | Hotbit |
AIRX | AIRX | – |
TE-FOOD | TFD | DDEX |
Berry | BERRY | HitBTC IDEX |
EIP827 是以太坊平台一种Token标准提案
EIP827 即 ERC827 标准的提案,是以太坊平台众多提案之一,为 Token 标准提案,它是对 ERC20 标准的扩充。
ERC827 标准在 ERC20 的基础上增加了三个接口 transferAndCall()
,transferFromAndCall()
,approveAndCall()
。
function transferAndCall(address _to, uint256 _value, bytes _data) public payable returns (bool) {
require(_to != address(this));
require(super.transfer(_to, _value));
require(_to.call(_data));
return true;
}
function transferFromAndCall(
address _from, address _to, uint256 _value, bytes _data
) public payable returns (bool) {
require(_to != address(this));
require(super.transferFrom(_from, _to, _value));
require(_to.call(_data));
return true;
}
function approveAndCall(address _spender, uint256 _value, bytes _data) public payable returns (bool) {
require(_spender != address(this));
require(super.approve(_spender, _value));
require(_spender.call(_data));
return true;
}
这三个函数中都有一个 call()
函数的操作,即允许用户通过该合约随意调用任意地址上的任意函数。以 transferAndCall()
为例,函数中转账操作完成后,会调用 _to
地址上的任意函数,并且参数 _data
由调用者任意指定。攻击者可以很容易地借用当前合约的身份来对 to
合约执行 任何操作,比如盗取 Token 或者绕开权限检查等。
ERC827 Token 合约设计和实现上允许用户自定义 call()
任意地址上任意函数来实现“接收通知调用”功能,攻击者可以很容易地借用当前合约的身份来进行任何操作。
这通常会导致以下危险的后果:
后果一:允许攻击者以缺陷合约身份来盗走其它 Token 合约中的 Token
后果二:与 ds-auth 之类的鉴权机制结合,绕过合约自身的权限检查
后果三:允许攻击者以缺陷合约身份来盗走其它 Token 账户所授权(Approve)的 Token
后果四:攻击者可传入虚假数据欺骗 Receiver 合约
DEX 和 DApp 开发者目前请勿与使用 ERC827 Token 的合约进行交互对接,否则可能会有严重的后果。
OpenZeppelin 已经移除 ERC827 合约模板
这些问题合约部分参照了 OpenZeppelin 提供的合约模板。安比(SECBIT)实验室随即向 OpenZeppelin 官方的 Github 仓库提出了issue。
目前 OpenZeppelin 官方仓库中 ERC827 合约的实现已经被移除,而 p0n1 在与 OpenZeppelin 讨论中一致认为,应将目前尚未被广泛采纳的提案实现放入一个单独的文件夹,标明a unstable draft with issue discussion link provided
。EIP827 提案的作者也随即做出了反馈。
存在问题的 ERC827 的合约有哪些
这个问题的描述及问题合约已收录至 智能合约风险列表, 该列表由安比(SECBIT)实验室发起共建并持续维护的 Token 合约问题列表,我们将不间断更新问题 Token 合约信息,同时也欢迎更多的小伙伴发现并更新更多漏洞和问题合约。
社区下一步做什么
目前 ERC827 合约的实现已经被转移到新的仓库中。
对于ERC 827标准的后续讨论和改进也将在此仓库中完成。
安比(SECBIT)实验室小伙伴也将积极参与到 ERC 827 标准的后续跟进中,共同致力于打造更加良好的以太坊生态。同时我们也提醒项目方,发行合约一定要慎之又慎,谨慎使用尚未被广泛认可的标准提案。项目方务必做好测试和审计工作,寻求专业的审计团队对合约进行审计,必要时遵守智能合约安全开发规范,引入安全审计流程,必要的时候采用形式化验证 手段,确保万无一失。
智能合约形式化验证示例:https://github.com/sec-bit/tokenlibs-with-proofs
参考文献
[1] ERC827 Token Standard (ERC20 Extension) https://github.com/ethereum/EIPs/issues/827
[2] ERC223及ERC827实现代码欠缺安全考虑 —— ATN Token中的CUSTOM_CALL漏洞深入分析
https://mp.weixin.qq.com/s/kgo_FA1lCvuglC9cG-V2cQ
[3] ERC827: abuse of CUSTOM_CALL will cause unexpected result #1044
https://github.com/OpenZeppelin/openzeppelin-solidity/issues/1044#issuecomment-399789610
[4] 智能合约风险列表(awesome-buggy-erc20-tokens) https://github.com/sec-bit/awesome-buggy-erc20-tokens
[5] 安⽐(SECBIT)实验室携⼿路印(Loopring)共同发布智能合约风险列表
https://mp.weixin.qq.com/s/XbXlrmt0fi9IgxicmdAF0w
[6] ERC827 Token Standard https://github.com/windingtree/erc827
以上数据均由安比(SECBIT)实验室提供,合作交流请联系info@secbit.io。
安比(SECBIT)实验室
安比(SECBIT)实验室专注于区块链与智能合约安全问题,全方位监控智能合约安全漏洞、提供专业合约安全审计服务,在智能合约安全技术上开展全方位深入研究,致力于参与共建共识、可信、有序的区块链经济体。
安比(SECBIT)实验室创始人郭宇,中国科学技术大学博士、耶鲁大学访问学者、曾任中科大副教授。专注于形式化证明与系统软件研究领域十余年,具有丰富的金融安全产品研发经验,是国内早期关注并研究比特币与区块链技术的科研人员之一。研究专长:区块链技术、形式化验证、程序语言理论、操作系统内核、计算机病毒。