一文理清过度授权的是是非非

什么是过度授权

忘记在哪里看过一个脑静急转弯了。大致内容:如果你的区块链硬件钱包有10万元,玩dapp你最多能亏多少钱?答案显而易见:10万。当然,这个10万有很大可能不是dapp内部逻辑导致的亏损,而是因为它的钱包授权给了恶意DAPP,这个恶意dapp盗走了他的10万元。

这就是区块链世界的”黑暗森林“,大家都在猎杀金钱,活下去的的唯一途径就是别被第二者发现我们的低级错误。

过度授权的案例

案例1: 2021 年 2 月份 ,中心化金融协议 Primitive由于合约漏洞,攻击者利用过度授权机制盗走了一部分资金。 https://cryptopotato.com/defi-protocol-primitive-finance-self-hacks-to-prevent-exploit/
案例2:2021 年 2 月份, https://rekt.news/furucombo-rekt/
案例3:我身边的朋友,自己偶尔玩玩dapp,自己本身也是做技术的,还被过度授权盗走了1000多U
20220529004454
更多过度授权案例 百度搜索:过度授权 或者 infinite approval

过度授权剖析

平时区块链转账,我们也没有使用过授权这个概念。授权这个概念大概是随着defi的兴起而火起来的,defi summber随便一个年化都很高,热钱涌动,进来了很多人。而这些defi大部分都是dapp,你需要授权给这些app使用你的资金,然后去赚钱。本质上,无论日常地址之间直接转账还是说dapp授权交易都是一个区块链的交易。怎么去区分和理解呢,如下图大致画 了一下我们平时转账交易和dapp授权的区别
日常转账交易(大致画了一下)
20220529005545
dapp授权交易
20220529010907

一言以蔽之,正常交易转账是自己直接转给地方地址。dapp授权是给第三方一个使用自己资金的权限,授权的时候可以指定币种和金额。
大家使用比较多的小狐狸授权页面如下,一旦遇到类似的页面,不熟悉的一定不要授权或者读取清楚每一个字。
20220529011159

ERC20标准

这个部分有一点偏技术,简单看一下,对于后边的内容会理解的更加深刻。ERC20标准大致是一个规定了以太坊区块链上的数字资产的生成,存储,转移等一系列操作的标准。有了这个标准之后,所有遵守ERC20协议的所有token之间既可以互操作了。

正常的erc20合约标准,大致有如下接口

https://eips.ethereum.org/EIPS/eip-20

1
2
3
4
5
6
7
8
9
10
11
12
// https://github.com/ethereum/EIPs/issues/20
contract ERC20 {
function totalSupply() constant returns (uint totalSupply);
function balanceOf(address _owner) constant returns (uint balance);
function transfer(address _to, uint _value) returns (bool success);
function transferFrom(address _from, address _to, uint _value) returns (bool success);
function approve(address _spender, uint _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint remaining);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}

  • totalSupply token的总供应量
  • balanceOf 查询某一个地址的token余额
  • transfer 转移token从一个地址到另外一个地址
  • transferFrom 第三方从一个地址Token转移到一个地址
  • approve 给予其他地址授予token使用权限
  • allowance 查询既定的地址授予了哪些全新
  • Transfer 事件,token 发生转移就会有这个事件日志
  • Approval 授权事件

看到了吗?erc20标准就6个函数2个事件。让人失望的是,标准中没有我们期望看到的撤销授权的函数方法!!! 具体啥原因我暂时没有想清楚

从代码角度看,我的钱是怎么被恶意dapp盗走的

这里假设有两个用户A和B。用户A有100U 而且授权给了B使用这100U 。过程如下

  1. A调用 approve(address(B), 100),授予B使用A的100Usdt的权限
  2. B使用的时候需要检查A到底给自己了多少usdt的使用额度:allowance(address(A), address(B))
  3. B知道了自己的使用额度之后调用转账transferFrom(address(A), address(B), 100) 把100U 从A转到B

过程就是这么的简单!!!!!

虽然 transferFrom 函数被用来了盗用token,但是的设计目标是允许经过授权的地址使用我的token,在如下场景还是有不少用的

  • 让他人代付gas费用
  • dapp中允许dapp支配自己的资金去赚取收益
  • 订阅web3的一些服务,自动扣款等
  • 代币归集,如果100000 个地址需要归集,你需要给10000个地址打手续费,而且每个地址都有零星的不能用的小数点后边N位的以太坊,好恐怖!如果授权就不一样了

手续费是谁来付

1
2
3
4
5
假设:A账号有10000个token代币,B账号没有token代币,C账号也没有token代币!
那么:A账号 委托 B账号 转给C账号 100个token代币 怎么来实现呢?
首先:A账号 和 B账号建立一种委托关联,登录A账户执行approve(b,100)方法结果为:结果:_allowed[A][B] = 100token
然后:在执行登录B账户执行transferFrom(A,C,100),这里的B就是委托账号发送者,gas从B扣,必须确保token数量小于_allowed[A][B]
总结:其实就是A转入C,但是要经过B的账号来发送交易!

如何防范过度授权威胁

  • 不要使用来源不明或者自己不信任的dapp
  • 定期使用撤销授权工具清理授权
  • 养成良好的习惯,经常用来玩dapp的钱包别放太多资金。

如何手动撤销过度授权

  1. 一些钱包例如,tokenpocket ,imtoken ,mathwallet 内部都内置了过度授权清理工具。
  2. 一些第三方网站,例如https://approved.zone/ ,debank,cointool 也都提供了类似的工具(提示:别因为清理授权被钓鱼了)
  3. 清理授权的过程是需要花费一定的gas 的

过度授权一定能撤销干净吗

一种猜想

既然过度授权危害这么大。我有一些解决类似问题的想法。
建立一个权威的公用合约A。这个合约由一个dao组织运行,dapp项目方需要提供合约地址给合约A,一旦加入到合约A的白名单,就代表被加入的合约在一定程度上做了背书。加入白名单的项目方要么提供实名信息要么提供一些token质押,防止作恶。

在用户使用dapp的时候,不是直接授予权限给不受信任的dapp而是直接授权给dao运营的合约A。然后由合约A代理用户向目标合约做交互。

等于说在用户和目标dapp之间做了一个隔离,这个在一定程度上能解决授权过渡问题。

其他

其实,这个话题展开的话,能说很多。包括从代码角度可以写一个demo来演示都是没问题的。只有真正的让用户看到了过度授权的危害才能真正的警醒用户授权的时候留一个心眼。而屡屡有用户因为过度授权上当受骗,大概是因为狼来了的故事挺多了,反正这事也不会发生在我身上。

哎,这个话题又涉及到哲学高度了,涉及到了人类学了。也罢,到此为止。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2022 zzj
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信