对于开发者来说,AUTH/AUTHCALL?机制非常具有吸引力。它可以让人们创建调用者来实现不同的批量处理策略、gas抽象模型和复杂的账户抽象方法等。
这种灵活性源于这一机制赋予了开发者极大的自由。AUTH/AUTHCALL?机制不要求开发者遵循特定的模式,而是要求用户签署一个?commit?哈希值,让开发者基于?commit?自行设置限制。
然而,这种灵活性是以牺牲安全性为代价的。在本文中,我想要介绍一种更简单的替代方案。这个方案具备?AUTH/AUTHCALL?机制的绝大多数优点,但是风险远低于后者。
为什么签署一个AUTH?commit?所带来的风险高于签署一个与存在漏洞/恶意合约相关的事务?
用户在签署与合约相关的事务时,所承担的风险是已知的,即,可能会损失在该合约控制范围内的资产。比方说,用户给一个ERC20合约签署了批准事务,授权恶意的DEX合约。这个恶意DEX合约就可以提走用户在ERC20合约中的全部余额。但是,它无法从该用户的其它ERC20合约中提走代币,除非得到该用户的批准。它也不能代表用户进行其它操作,因为这也需要专门获得用户的批准。
LendHub被黑简析:系LendHub中存在新旧两市场:金色财经报道,据慢雾安全区情报,2023 年 1 月 13 日,HECO 生态跨链借贷平台 LendHub 被攻击损失近 600 万美金。慢雾安全团队以简讯的形式分享如下:
此次攻击原因系 LendHub 中存在两个 lBSV cToken,其一已在 2021 年 4 月被废弃但并未从市场中移除,这导致了新旧两个 lBSV 都存在市场中。且新旧两个 lBSV 所对应的 Comptroller 并不相同但却都在市场中有价格,这造成新旧市场负债计算割裂。攻击者利用此问题在旧的市场进行抵押赎回,在新的市场进行借贷操作,恶意套取了新市场中的协议资金。
目前主要黑客获利地址为 0x9d01..ab03,黑客攻击手续费来源为 1 月 12 日从 Tornado.Cash 接收的 100 ETH。截至此时,黑客已分 11 笔共转 1,100 ETH 到 Tornado.Cash。通过威胁情报网络,已经得到黑客的部分痕迹,慢雾安全团队将持续跟进分析。[2023/1/13 11:11:00]
相较之下,EIP3074不仅要求用户签署“空白支票”,而且假设调用者是诚实且没有漏洞的。一个恶意/存在漏洞的调用者可以代表用户执行任何操作?——访问用户持有的资产,代表用户进行投票,控制用户所有的合约等。
安全公司:Starstream Finance被黑简析:4月8日消息,据Agora DeFi消息,受 Starstream 的 distributor treasury 合约漏洞影响,Agora DeFi 中的价值约 820 万美金的资产被借出。慢雾安全团队进行分析后以简讯的形式分享给大家。
1. 在 Starstream 的 StarstreamTreasury 合约中存在 withdrawTokens 函数,此函数只能由 owner 调用以取出合约中储备的资金。而在 April-07-2022 11:58:24 PM +8UTC 时,StarstreamTreasury 合约的 owner 被转移至新的 DistributorTreasury 合约(0x6f...25)。
2. 新的 DistributorTreasury 合约中存在 execute 函数,而任意用户都可以通过此函数进行外部调用,因此攻击者直接通过此函数调用 StarstreamTreasury 合约中的 withdrawTokens 函数取出合约中储备的 532,571,155.859 个 STARS。
3. 攻击者将 STARS 抵押至 Agora DeFi 中,并借出大量资金。一部分借出的资金被用于拉高市场上 STARS 的价格以便借出更多资金。[2022/4/8 14:12:38]
更糟糕的是,调用者随时都可以作恶,因为nonce实现是由调用者控制的。存在漏洞/恶意的nonce逻辑实现可以重放用户过去的事务。如果?commit?验证的其它部分的逻辑也存在漏洞,调用者就可以利用这个nonce逻辑实现来代表用户执行任何操作。即使漏洞被发现,用户也无法撤回空白支票。这个外部账户已经被永久入侵了。
慢雾简析Qubit被盗原因:对白名单代币进行转账操作时未对其是否是0地址再次进行检查:据慢雾区情报,2022 年 01 月 28 日,Qubit 项目的 QBridge 遭受攻击损失约 8000 万美金。慢雾安全团队进行分析后表示,本次攻击的主要原因在于在充值普通代币与 native 代币分开实现的情况下,在对白名单内的代币进行转账操作时未对其是否是 0 地址再次进行检查,导致本该通过 native 充值函数进行充值的操作却能顺利走通普通代币充值逻辑。慢雾安全团队建议在对充值代币进行白名单检查后仍需对充值的是否为 native 代币进行检查。[2022/1/28 9:19:19]
编写一个正确的调用者程序很难,而且我们几乎可以肯定,调用者会不定期出现错误,从?EIP3074最后列出的调用者应该警惕的检查/漏洞/情况非详尽清单中可见一斑。这份清单势必会变得越来越长,很可能伴随着痛苦的发现过程。
Grim Finance 被黑简析:攻击者通过闪电贷借出 WFTM 与 BTC 代币:据慢雾区情报,2021 年 12 月 19 日,Fantom 链上 Grim Finance 项目遭受攻击。慢雾安全团队进行分析后以简讯的形式分享给大家。
1. 攻击者通过闪电贷借出 WFTM 与 BTC 代币,并在 SpiritSwap 中添加流动性获得 SPIRIT-LP 流动性凭证。
2. 随后攻击者通过 Grim Finance 的 GrimBoostVault 合约中的 depositFor 函数进行流动性抵押操作,而 depositFor 允许用户指定转入的 token 并通过 safeTransferFrom 将用户指定的代币转入 GrimBoostVault 中,depositFor 会根据用户转账前后本合约与策略池预期接收代币(预期接收 want 代币,本次攻击中应为 SPIRIT-LP)的差值为用户铸造抵押凭证。
3. 但由于 depositFor 函数并未检查用户指定转入的 token 的合法性,攻击者在调用 depositFor 函数时传入了由攻击者恶意创建的代币合约地址。当 GrimBoostVault 通过 safeTransferFrom 函数调用恶意合约的 transferFrom 函数时,恶意合约再次重入调用了 depositFor 函数。攻击者进行了多次重入并在最后一次转入真正的 SPIRIT-LP 流动性凭证进行抵押,此操作确保了在重入前后 GrimBoostVault 预期接收代币的差值存在。随后 depositFor 函数根据此差值计算并为攻击者铸造对应的抵押凭证。
4. 由于攻击者对 GrimBoostVault 合约重入了多次,因此 GrimBoostVault 合约为攻击者铸造了远多于预期的抵押凭证。攻击者使用此凭证在 GrimBoostVault 合约中取出了远多于之前抵押的 SPIRIT-LP 流动性凭证。随后攻击者使用此 SPIRIT-LP 流动性凭证移除流动性获得 WFTM 与 BTC 代币并归还闪电贷完成获利。
此次攻击是由于 GrimBoostVault 合约的 depositFor 函数未对用户传入的 token 的合法性进行检查且无防重入锁,导致恶意用户可以传入恶意代币地址对 depositFor 进行重入获得远多于预期的抵押凭证。慢雾安全团队建议:对于用户传入的参数应检查其是否符合预期,对于函数中的外部调用应控制好外部调用带来的重入攻击等风险。[2021/12/19 7:49:04]
此外,恶意参与者可以编写一个看似无害的调用者程序,但是故意留下一个细微的漏洞,等到大量外部账户授权该调用者之后才会被攻击者利用。
慢雾:Polkatrain 薅羊毛事故简析:据慢雾区消息,波卡生态IDO平台Polkatrain于今早发生事故,慢雾安全团队第一时间介入分析,并定位到了具体问题。本次出现问题的合约为Polkatrain项目的POLT_LBP合约,该合约有一个swap函数,并存在一个返佣机制,当用户通过swap函数购买PLOT代币的时候获得一定量的返佣,该笔返佣会通过合约里的_update函数调用transferFrom的形式转发送给用户。由于_update函数没有设置一个池子的最多的返佣数量,也未在返佣的时候判断总返佣金是否用完了,导致恶意的套利者可通过不断调用swap函数进行代币兑换来薅取合约的返佣奖励。慢雾安全团队提醒DApp项目方在设计AMM兑换机制的时候需充分考虑项目的业务场景及其经济模型,防止意外情况发生。[2021/4/5 19:46:39]
如果攻击者没有直接或立即利用这个漏洞从用户那里窃取资金,这个漏洞可能很长时间都不会被发现。
治理劫持示例
恶意去中心化交易所EveSwap为其用户编写了一个调用者程序。这个调用者程序通过空投EVE代币来为用户提供gas资助,并批量处理用户的批准和转账事务。
EveSwap的调用者程序看似无害,而且永远不会窃取用户的代币,因为这样马上就会露馅。
用户很开心。交易都成功了,交易费也很便宜。几个月来平安无事。
然而,每当有人使用EveSwap交易AliceSwap的治理代币ALI时,会自动将用户的AliceSwap投票权委托给EveSwap。
一旦授权人数达到某个阈值,EveSwap就会通过治理提案劫持AliceSwap。
EveSwap用户不太可能注意到这个过程,因为交易总是成功的,但是最终会给AliceSwap带来毁灭性的打击。
跨链重放示例
EIP3074合理地建议?commit?应该包含?chainid。但是,这是由调用者,而非协议执行的。在另一条链上有着相同地址的调用者可能会跳过该检查。
EveSwap在兼容EVM的BobSpongeChain上运行,后者支持EIP3074。EveSwap在BobSpongeChain上部署了一个诚实的调用者。
用户使用该调用者在BobSpongeChain上交易,然后使用桥将资产转移到以太坊上。
EveSwap使用同一个部署密钥在以太坊上部署了另一个地址相同的调用者。这个在以太坊上的调用者不会检查?commit,只会检查?ownerOnly,并充当其所有者的通用AUTH/AUTHCALL代理。
这样一来,EveSwap就可以劫持用户在以太坊上的外部账户并卷走他们的资产了。
用户从未在以太坊上交易过,运行在BobSpongeChain上的调用者程序又经过了严格的安全审查。尽管如此,用户还是丢失了全部资产。
以太坊通过EIP155的重放保护来防范这种情况。AUTHCALL没有重放保护。由于所有?commit?检查都交给调用者完成,我们失去了以太坊提供的一切交易保护。攻击是在所难免的,因为保护措施很随意。如果要接受EIP3074,AUTH消息必须明确包含?chainid,而非将其作为?commit?的一部分。
我们还能采取什么别的手段?
我的提议是实现一个更明确的机制,在协议层面强制规定?commit?的含义。commit结构将是类型化的,钱包会以用户可读的形式将commit呈现出来。用户可以确切地知道事务是什么样子的,并确信这个事务不会在任何链上重放,无需依赖于调用者程序开发者的品行和能力。
一个可能的实现:
AUTH?将使用包含授权调用列表的类型化结构代替?commit?哈希值。每个调用都将指定{nonce,to,gas,calldata,value,chainid}。签名将被验证,整个授权调用列表将保存为?authorized_transactions?而非?authorized?地址变量。
AUTHCALL?将得到一个新的参数?index,该参数指向最后一个?AUTH?创建的列表中的地址。
用户地址的nonce将随?AUTHCALL?递增。nonce并非由调用者存储,而是实际的账户nonce。
利:
用户可以清楚地了解情况。
安全性由协议保障。
依然支持批处理和账户抽象。
弊:
nonce实现,不支持并行。
复杂调用者程序的事务处理起来很繁琐,因为用户必须查看并接受整个调用列表。
不同的实现可能支持不同的nonce方案。但是,无论我们使用什么机制,该机制必须由协议而非调用者执行。
无论如何都应该避免让复杂调用者执行大量用户调用。复杂操作应该作为普通的智能合约实现,而非尝试实现使用多个外部账户调用的算法。
替代方案:完全避免硬分叉
还有一个选择是完全避免AUTH机制,并通过?vbuterin?建议的另一种交易池来解决账户抽象和批量处理问题。
利:
无需硬分叉,可由智能合约和可以感知这些智能合约的节点支持。
可用于一切支持EIP3074的实现,而不会引入额外的风险。
弊:
不向后兼容已有的外部账户。用户需要部署一个合约钱包并将资产转移到该钱包内。
除非要求在不迁移的情况下支持已有的外部账户,否则这个选择看起来更安全。
原文链接:
https://blog.mycrypto.com/eip-3074/
作者:?MaartenZuidhoorn
翻译&校对:?闵敏&?阿剑
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。