午夜咖啡午夜咖啡

jolestar 的文章与笔记。

Post

allowance 误解与 ERC20 授权漏洞

2018-05-24 13:39:34Post

很多智能合约漏洞不是源于复杂攻击技巧,而是开发者对一个看似基础的授权字段理解不完整,再叠加语言默认值和整数边界行为,最后把整个资产模型打穿。

在慢雾区里看到 EDU 的一个智能合约漏洞,我的第一反应是:很多人抄智能合约时,可能根本没把 allowance 这个字段真正想明白。

allowance 的作用,本质上是允许用户授权第三方在一定额度内,从自己的账号里转账。它的设计目的,是为了让 token 能更自然地进入合约支付场景。

ETH 上实现这个机制,一般就是放一个嵌套 map,保存类似 “A 允许 B 从自己账户里转 10 块钱” 这样的授权关系。approve 方法就是干这个的。然后 B 就可以通过 transferFrom 来从 A 的账户里转账。

正常逻辑下,转账前当然应该先检查授权额度。但这个漏洞的问题在于:代码没有把这件事处理对,结果把授权额度一路减穿了。本来 B 最多只能扣 10,结果一下子就能把 A 账户里的余额全部拿走。

如果问题只停留在已有授权关系里,危害还没这么夸张。但 ETH 这类场景还有个默认规则:从 map 里取值时,如果这个键不存在,就会返回默认值,比如数字就是 0

这就意味着,按这个逻辑,每个用户对其他任何用户,天然都“存在一个额度为 0 的授权”。而如果你的扣减逻辑又能把这个边界打穿,那问题就会从“授权检查有 bug”升级成“任何人都可能转走任意账户里的 token”。

严格说,uint256 不会真的变成负数,而是在减到 0 以后发生溢出。这里我沿用了当时解释这个漏洞时的直观说法,但本质问题就是:开发者把授权边界处理错了。

原微博中的媒体