重入攻击仍然是一个挑战,现有的防御手段主要集中在协议源代码层面,仅在合约进入 runtime 状态前生效
「运行时保护」是 DeFi 安全的重要补充,它以「保护执行结果」为目的,确保协议的执行与其预期设计一致
EVM 的设计不支持「运行时保护」,因为智能合约无法访问 runtime 状态全部上下文信息
Artela 探索一种 EVM+Extension 的执行层范式,增强执行层以消除重入攻击
Artela 通过 Aspect Programming 实现链上「运行时保护」扩展
我们逐步展示了如何通过 Aspect 防范对 Curve 合约的重入攻击
尽管重入攻击是一个众所周知的问题,并且出现了许多风险控制措施,但在过去的两年中,涉及此类攻击的安全事件仍在不断发生:
Curve Finance 攻击(2023 年 7 月)—6000 万美元,Curve 因其合约编程语言 Vyper 编译缺陷遭受重入攻击。
Origin Protocol 攻击(2022 年 11 月)—700 万美元,稳定币项目 Origin Dollar(OUSD)遭受了重入攻击。
Siren Protocol 攻击(2021 年 9 月)—350 万美元,AMM 池遭受重入攻击。
Solidity编译器发布0.8.19版本,引入用户定义值类型定义运算符:2月23日消息,以太坊编程语言 Solidity 推出 Solidity 编译器 0.8.19 版本,最新版本包括一系列改进,以及引入用户定义值类型定义运算符,防止运行时字节码中的死代码。@sifislag 报告的内部库函数和通过模块调用的自由函数的问题已在此版本中得到修复。团队建议使用低于 0.8.0 的 Solidity 版本的用户进行升级。[2023/2/23 12:25:32]
Cream Finance 攻击(2021 年 8 月)—1880 万美元,攻击者利用重入漏洞进行二次借贷。
目前,防范重入攻击的重点集中在智能合约的源代码层面,措施包括集成 OpenZeppelin 的 ReentrancyGuard,以及对合约逻辑代码进行安全审计,以避免预定义的安全隐患。
这种方法被称为「白盒」解决方案,旨在在源代码层面规避漏洞,以最小化逻辑错误。然而,其主要挑战在于无法防御未知隐患。
将合约从源代码「转化」为实际 runtime 是个具有挑战性的过程。每一步可能为开发人员带来无法预料的问题,而合约源代码本身可能无法全面涵盖所有潜在情况。在 Curve 的案例中,由于编译器问题,即使协议源代码是正确的,最终运行结果与协议的预期设计之间仍可能存在差异。
以太坊编程语言Solidity发布最新版本编译器Solidity 0.8.18,支持巴黎硬分叉:金色财经报道,以太坊编程语言Solidity发布最新版本的Solidity编译器Solidity0.8.18,新版本的功能包括:禁用CBOR元数据、支持巴黎硬分叉、弃用selfdestruct、从Yul生成EVM字节码。团队建议所有Solidity开发人员升级到版本0.8.18以利用这些改进和优化。[2023/2/2 11:43:19]
仅仅依靠协议在源代码和编译层面的安全性是不足够的。即使源代码看起来毫无瑕疵,由于编译器问题,漏洞仍可能意外出现。
与现有的风险控制措施集中在协议源代码层面并在运行之前生效不同,运行时保护涉及协议开发人员编写运行时保护规则和操作,以处理运行时的未预料情况。 这有助于对运行时执行结果进行实时评估及应对。
运行时保护在增强 DeFi 安全性方面至关重要,是现有安全措施的重要补充。通过以「黑盒」方式保护协议,它通过确保最终运行结果与协议预期设计相一致来增强安全性,而无需直接干涉合约代码执行。
Nethermind:Warp 已转译和编译 Uniswap V3:10月9日消息,以太坊客户端 Nethermind 表示, Warp 项目的下一个重要里程碑已经实现,已成功转译和编译 Uniswap V3 为 Uniswap V3 Warped(UniStark),目前正在完成一个 hardhat 插件,允许在转译的 Cairo 上运行所有 Solidity hardhat 测试。也就是说,Warp 已经转换和部署了 Uniswap V3 存储库中的每个 Solidity 文件,只需对源代码进行少量更改。
注,Warp 旨在将任意 Solidity 合约转换到 Cairo,并将它们部署到 StarkNet 上。6 月份,Nethermind 上线 Warp 2.0,支持将 Solidity 合约转换为 Cairo 合约,以部署到 StarkNet 上。[2022/10/9 12:50:09]
不幸的是,EVM 设计不支持在链上实现运行时保护,因为智能合约无法访问完整的运行时上下文。
如何克服这一挑战?我们认为以下先决条件是必要的:
一个专门的模块,可以访问跨智能合约的所有信息,包括整个交易上下文。
从智能合约获得必要的授权,使模块有权根据需要回撤 (revert) 交易。
确保模块的功能在智能合约执行后和状态提交之前生效。
zkSync CEO:zkSync拟于年底完成支持所有的预编译:9月22日消息,在由万向区块链实验室主办的第八届区块链全球峰会上,以太坊二层网络zkSync首席执行官Alex Gluchowski探讨了V神曾提及的5种EVM兼容方案:即类型1(完全等效于以太坊)、类型2(完全等效EVM)、类型2.5(与evm相当,不包括gas费用)、类型3(几乎等同于EVM)以及类型4(相当于高级语言) 。Gluchowski称,从性能差异的角度来看,类型3、类型2、类型2.5之间并不显著,但可以从类型4开始,通过选择好的基本范式框架之内添加功能,不断地提高与EVM的兼容性。zkSync计划于年底完成支持所有的预编译。目前zkSync处于EVM兼容的类型2.5,为了提高兼容性,我们需要支持与以太坊完全相同的Gas计算,并且支持存储和共识的兼容性。[2022/9/22 7:13:45]
EVM 在解决上述挑战中目前面临限制,难以容纳更多创新。在模块化区块链的范式下,执行层需要探索 go beyond EVM 的突破。
Artela 的思路是 EVM + native extension,通过构建 EVM 的 WASM 原生扩展层以实现 go beyond EVM。
我们推出了 Aspect Programming,这是支持 Artela 区块链的一种编程框架,支持在区块链上进行原生扩展。
BlockSec:以太坊分叉因Geth旧版本在处理预编译合约调用时未考虑异常值的处理:BlockSec团队发文称,北京时间2021年8月27日20点50分左右(区块高度13107518),以太坊突然出现分叉。BlockSec通过分析Geth的代码版本修改和这笔造成分叉的交易(0x1cb6fb36633d270edefc04d048145b4298e67b8aa82a9e5ec4aa1435dd770ce4)厘清了以太坊分叉的根本原因:Geth旧版本在处理预编译合约调用时,并未考虑特殊情况(corner case)下参数值的处理,从而引发重叠拷贝(overlapping copy),导致返回值异常。该漏洞(CVE-2021-39137)已提交Geth官方,目前尚未披露细节,但攻击者已经利用漏洞实施了攻击。
BlockSec总结称,通过对整个攻击流程的梳理和Geth源代码的分析,BlockSec认为根本原因在于Geth旧版本在处理预编译合约的调用时并未考虑异常值的处理,导致攻击者利用该漏洞实施了重叠拷贝,影响了返回值,最终导致分叉的出现。由于Geth是BSC、HECO、Polygon等公链的基础,因此该漏洞影响范围甚广。目前各公链也先后推出了升级和补丁,BlockSec也呼吁各相关节点尽早升级打上补丁,以确保基础设施的安全。[2021/8/28 22:42:41]
Aspect 是可编程的原生扩展模块,用于在运行时动态集成自定义功能到区块链中,作为智能合约的模块化补充,增强链上功能性。
Aspect 的特性是能够访问区块链基础层的系统级 API,并在交易生命周期的各个切点(Join Point)添加扩展逻辑。智能合约可以绑定指定的 Aspect 以触发扩展功能。当交易调用智能合约时,该交易也会经由与该合约关联的 Aspect 处理。
Aspect 可以记录每个函数调用的执行状态,并防止在回调函数执行期间发生重入。当在回调函数执行期间发生重入调用时,Aspect 会检测到并立即回撤该交易,防止攻击者利用重入漏洞。通过这种方法,Aspect 有效地消除了重入攻击,确保智能合约的安全性和稳定性。
Aspect 实现运行时保护的关键属性:
可在智能合约执行后和状态提交前触发:Aspect 模块可设置为在智能合约执行后但在状态提交前激活。
完整的交易上下文访问:Aspect 可以访问完整的交易上下文,包括整个交易信息(方法,参数等)、调用栈(执行过程中所有内部合约调用)、状态上下文变更以及所有交易触发的事件。
系统调用能力:Aspect 可以进行系统调用,并在必要时发起交易回撤。
与智能合约的绑定和授权:智能合约可以绑定到 Aspect,并授予 Aspect 参与交易处理的权限。
本章我们探讨如何在链上实现 Aspect 的运行时保护。
可以在「preContractCall」和「postContractCall」的切点(Join Point)中部署一个实际的「合约保护意图」Aspect,以防止重入攻击。
preContractCall: 在跨合约调用执行之前触发
postContractCall: 在跨合约调用执行后触发
为进行重入保护,我们的目标是在调用结束之前阻止合约重入。通过 Aspect,我们可以通过在交易生命周期的切点处添加特定逻辑来实现这一目标。
在「preContractCall」切点中,Aspect 监控合约调用堆栈。如果在调用堆栈中有任何重复调用(这意味着我们锁定的调用中出现了意外重入),Aspect 将会回撤该调用。
我们编写了 Curve 模拟合约并复刻重入攻击,以更易理解的方式重现了这个过程。合约代码如下:
可以看到,上述合约的 add_liquidity 和 remove_liquidity 都由同一个重入锁 lock 进行了保护,这意味着如果重入保护正常工作,无法通过改锁重入被保护函数(例如,在 remove_liquidity 中调用 add_liquidity)。
使用 vyper 编译器 0.2.15、0.2.16 或 0.3.0(这些版本存在已知的重入保护问题)编译上述合约。
然后,我们部署上述受害者合约,并使用以下合约对其进行攻击:
模拟实际攻击,此合约的 attack 方法尝试通过其 fallback 函数从 remove_liquidity 方法重入 add_liquidity。如果实际发生了重入,可在 receipt 中观察到在 RemoveLiquidity 事件之前记录了一个 AddLiquidity 事件。
现在让我们使用 Aspect 来保护受攻击的合约。在执行以下操作之前,请先完成以下步骤:
1、部署 Aspect
2、将受害合约与 Aspect 绑定
如果对 Aspect 操作不熟悉,可以首先查看我们的开发者指南先行了解。
完成上述操作后,现在让我们尝试再次调用 attack 方法,以检查操作是否会成功进行。
从动图(文末原文链接可查看)中我们可以看到,重入交易已经被 revert,这意味着我们的 Aspect 正在成功保护受害合约免受重入攻击。
最近对 Curve 的攻击再次说明了没有 100% 完全安全的协议。仅仅将重心放在协议的源代码和编译级别的安全性上是不足够的。即使源代码看起来毫无瑕疵,由于编译器问题,漏洞仍然可能意外出现。
为了增强 DeFi 的安全性,运行时保护变得至关重要。通过以「黑盒」方式保护协议,确保协议的执行与其预期设计一致,可以有效地防止运行时的重入攻击。
我们复刻了 Curve 合约并完全模拟了其近期的重入攻击,并以更易理解的方式再现了整个过程。利用 Aspect 编程作为一种新方法,实现链上运行时保护,我们逐步展示了如何用 Aspect 保护受害合约。我们的目标是帮助根除 Curve 等 DeFi 协议可能遭受的重入攻击,从而增强整个 DeFi 领域的安全性。
通过 Aspect Programming,开发人员不仅可以在安全领域实现链上运行时保护,还能实现诸如意图、JIT 和链上自动化等前所未有的创新用例。除此之外,这个以 Cosmos SDK 为基础的通用框架将不仅支持 Artela 区块链,更能支持其他区块链构建基于自己执行层的 native extension。
金色财经
企业专栏
阅读更多
Foresight News
金色财经 Jason.
白话区块链
金色早8点
LD Capital
-R3PO
MarsBit
深潮TechFlow
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。