今日,跨链 DEX 聚合器 Transit Swap 遭受攻击,导致大量用户的资金从钱包中被取出。 截至目前,预计损失超 2300 万美元。
发现被盗后,Transit Swap 技术团队紧急暂停服务,合约已完全暂停,无法进行任何操作。发稿前 Transit Swap 官方发布公告称,此前黑客攻击事件原因系代码错误,目前已确定黑客 IP、电子邮件地址,以及相关的链上地址。Transit Swap 团队表示将尽力追踪黑客,并尝试与黑客沟通,帮助用户挽回损失。
慢雾分析,此次攻击的主要原因在于 Transit Swap 协议在进行代币兑换时并未对用户传入的数据进行严格检查,导致了任意外部调用的问题。具体而言,路由合约本身没有对 transferFrom 参数进行任何限制、也并未对解析后的兑换合约地址与调用数据进行检查。攻击者利用路由代理合约、路由桥合约与权限管理合约均未对传入的数据进行检查的缺陷,通过路由代理合约传入构造后的数据调用路由桥合约的 callBytes 函数,实现了窃取所有对权限管理合约进行授权的用户的代币。
目前黑客已将 2500 BNB 转移到 Tornado Cash,剩余资金分散保留在黑客地址中。经过黑客痕迹分析发现,黑客存在从 LATOKEN 等平台存提款的痕迹。
此外,安全团队 PeckShield 已确认黑客资金流向。
与此前被盗项事件不同的是,Transit Swap 是 TokenPocket 钱包的闪兑服务提供商。这让大量用户实现了 “无感被盗” 的丝滑体验,也再一次向我们明确了加密市场 “黑暗森林” 的恐怖法则,即使是钱包背书的便捷 “闪兑” 服务,依然存在被盗隐患。
什么是闪兑?
目前,几乎所有钱包都嵌入了 DeFi 功能,而一些钱包出于易用性的考量,更是创造了 “闪兑” 这一概念并加以应用。
所谓闪兑,即和钱包深度整合,在产品中拥有更明显的独立入口、更简化的操作流程,更便捷的操作。使用闪兑用户可以方便、快速的完成加密资产交易。例如,“Approve”操作通常被简单的一键式集成在交易流程中,用户几乎是无感的。
或是因钱包内置集成,用户对其天然更具信任,也一定程度降低了防范意识。但究其本质,无外乎是钱包 app 集成的一款 DEX,与其他 DEX 并无差异。这也给本次安全事件留下了隐患。
合约授权潜藏了多少风险?
“没有人可以强行拿走你的加密资产”,是投资者对区块链特性的一种广泛共识。链上资产一旦被钱包所有,没有任何强制手段将其转移。但当我们使用 DEX 进行链上交易之时,DEX 是如何将一种资产拿走再转移给你另一种资产的?
授权就成为了这一切的关键。用户于 DEX 出售资产之前,需先执行 “Approve” 操作,这一操作之后合约便拥有了动用用户某种代币的权限。
或者描述的更加直白一些:只要你做了授权,无需打开钱包、无需执行操作、无需私钥,该合约就可以不经你的许可,支配你授权的资产。这是由以太坊的机制和授权模型所决定的,与项目方的道德操守、安全规范、代码审计都并无任何关系。
审计=安全?
即使授权之后合约拥有转移加密资产的能力,但这种能力只在合理的范围内使用,这依然是安全的。而如果经过可信安全机构审计,是否即表示这种能力不会被滥用,只在用户进行交易时转走交易额的必要资产?
静态来看,这一逻辑是成立的。就如同 Uniswap 尽管拥有随时将用户钱包清空的能力,但并不会真的这么做一样。但动态来看,这一逻辑依然是危险的。
现代软件开发,升级是一项必不可缺的能力。智能合约也是如此。在 Solidity 智能合约中,拥有 Transparent 和 UUPS 两种升级方法,借助于这两个功能,合约代理和升级几乎是业界合约的标配。
项目方是如何进行合约升级的呢?通常,用户所访问的合约并非直接运行业务逻辑的核心合约,而是一个 “代理合约”,代理合约接收到用户请求之后将其转发到核心的业务合约,再由业务合约进行处理。而合约升级即是更换掉最终转发至的业务合约。简单来说,智能合约尽管不可修改,但用户所最终访问的、运行业务逻辑的合约是可以替换的。这也是业界的通用做法。
而即便是最安全的合约,只要进行 “合约升级”,其业务合约就已发生变化,此前的审计报告也沦为了一张废纸。
简单来说,今天你所交互的合约是安全的,但明天访问同样的这个项目,可能他的安全性已经发生根本性改变。合约(或攻击合约的黑客)仍可能拥有转走你所有已授权资产的能力。
无限授权有多危险?
所幸的是,授权并不代表用户随时暴露于钱包清空的危险中下。授权机制还有一个重要规则即是授权是含有数量的。用户 “Approve” 合约一定数量的代币,合约最多只能动用这些数量,即使是钱包里该代币数量再多,合约也已无法动用。
但危险的是,大多数 DeFi 合约都在无所顾忌索取用户的“无限授权”,即在默认情况下,用户所 Approve 的代币数量为无限。
(一个典型的 “无限授权” 操作,授权金额高达 10 的 59 次幂数量级)
用户如何防范?
没有授权就没有安全隐患。在执行链上操作之时,如需执行 Approve 操作,用户应遵循 “用多少、授多少” 的原则。如果我只需卖出 1000 TOKEN,那即应手动修改 Approve 金额为 1000。在计算合约转移金额时是累积的,即若只授权 1000、本次金额恰好交易了 1000,合约授权额度恰好已耗尽。即使日后合约出现安全风险,也已无法再从用户钱包中转移走任何资产。
(用户可手动修改授权金额)
而对已经授权的用户来说,还可发起取消授权操作。(一个有趣的细节是,以太坊并不支持 “取消授权”,该操作本质是赋予合约“0” 金额的授权。)
常用取消授权网站如下(安全公司慢雾推荐):
1. Dappstar:https://tac.dappstar.io/#/
2. Revoke:https://revoke.cash/
3. Approved.zone:https://approved.zone/
4. Rabby Wallet
此外,一些区块链浏览器也支持用户查看并取消授权。
https://cn.etherscan.com/tokenapprovalchecker
https://bscscan.com/tokenapprovalchecker
DeFi被盗,谁的责任?
“黑暗森林”是广为流传的对于链上秩序的叙述了,也提醒着用户这个世界的危险性和高风险。但诸如此类的安全事件一再发生,真的可以全部归责于用户的安全意识吗?
在此类事件中,DeFi 项目对于用户授权毫无节制的索取是隐患的最初来源,几乎所有的项目,在索取授权之时其默认选项都是无限授权。尽管用户可以手动修改,但一个负责任的市场应承担投资者保护和用户教育的责任。
至今,仍有多少加密用户尚不清楚授权的危险?而在这种环境背景之下,项目方仍在索取危险极大的无限授权。
DeFi 滥用授权的情况早已成为业界惯例,而这一高危情况几乎危及所有用户的天量资产,其影响之深远、广泛、隐患之巨,恐怕尚未有一个安全隐患可以望其项背。该风险从根本上违背了 “没有人可以拿走钱包里的币” 这一朴素的直觉。这也是行业需要一直面临的风险和挑战。
被盗事件发生后,神鱼就已在推特做出呼吁,“呼吁一下项目方规范使用授权功能,用多少授权多少,不要无限授权,大家都放心。”
去中心化充满着机会与风险。还记得加密技术最初的愿景吗?“保护你的资产,没有人可以夺走你钱包里的加密货币。”而一个良性秩序的建立,需要的不是复杂的代码、晦涩的概念,确保每一个普通用户都能安全的使用加密技术,仍然需要行业里每一个参与者共同的努力。