区块链桥(跨链桥)常见的安全漏洞有哪些?

 2023-11-14 15:47:43发布 2023-11-14 15:48:03更新

实现区块链互操作性的基础是区块链桥,保证跨链桥接技术的安全性至关重要,区块链桥常见的安全漏洞包括验证机制不完善、原生代币处理方式不当以及配置错误。

什么是区块链桥

区块链桥,也称为跨链桥,其连接两个区块链,允许用户从一个链向另一个链发送加密货币。

区块链桥通过两个独立平台之间的代币转账、智能合约和数据交换等其他反馈和指令,实现了资金的跨链操作。

一种常见的区块链桥的操作如下:

  • 用户将资产A发送到原链上的一个存储地址,并支付过桥费;
  • 资产A被智能合约中随机选择的验证者或受信任的托管人锁定;
  • 在目标链上发布相同数量的资产A1,并将资产A1发送到目标链上的用户地址。

区块链桥为什么容易受到攻击

区块链桥本质上是脆弱的,主要有两个原因:

首先,区块链桥只是增加了潜在黑客的攻击面,增加了加密货币生态系统的复杂性,从而扩大了攻击范围。

其次,许多构建方式与它们桥接的区块链完全不同,缺乏更大的开发社区意味着代码没有被广泛和仔细地搜索以发现潜在的Bug。

除此之外,区块链桥增加了整个加密货币生态系统的整体风险,因为它们有可能将一个平台的漏洞(或多个漏洞)传播到许多其他平台。

常见的区块链桥安全漏洞

为了增强区块链桥的安全性,了解常见的跨链桥接安全漏洞并在启动前测试区块链桥十分重要。这些漏洞主要来自以下四个方面:

链上验证不足

对于简单的区块链桥,尤其是专为特定dApp设计的区块链桥,通常只有最低程度的链上验证。这些桥依靠集中式后端来执行基本操作,例如铸币、销毁和代币转移,所有验证都是在链下进行的。

而其他类型的桥则使用智能合约来验证消息并在链上进行验证。在这种情况下,当用户将资金存入链中时,智能合约会生成签名的消息并在交易中返回签名。

这个签名就会用作充值的证明,用于验证用户在另一条链上的提现请求。这一流程应该能够防止各种安全攻击,包括重放攻击和伪造充值记录。

但是,如果链上验证过程存在漏洞,攻击可能会造成严重损失。例如,如果区块链用默克尔树来验证交易记录,那攻击者就可以生成伪造证明。

这意味着,如果验证过程存在漏洞,攻击者就可以绕过证明验证,并在其账户中铸造新的代币。

某些区块链桥会实施“包装代币(wrapped tokens)”的概念。例如,当用户将DAI从以太坊转移到BNB Chain时,他们的DAI将从以太坊合约中取出,并在BNB Chain上发行等量的包装DAI。

但是,如果此交易没有正确验证,攻击者就可以部署恶意合约,通过操纵该功能,将包装的代币从桥接路由到错误的地址。

攻击者还需要受害者先批准跨链桥合约,才能使用“TransferFrom”功能转移代币,从而从跨链桥合约中卷走资产。

但棘手的是,许多跨链桥都会要求dApp用户无限地批准代币,这种做法很常见,它可以降低燃料费,但允许智能合约从用户的钱包中访问不限量的代币,会带来额外的风险。

攻击者会利用这些验证不足和批准过度,将代币从其他用户转移给自己。

链下验证不足

在某些跨链桥系统中,链下后端服务器在验证从区块链发送的消息的合法性时起着至关重要的作用。在这种情况下,我们要重点关注充值交易的验证。

有链下验证的区块链桥的工作原理如下:

  1. 用户与dApp交互,将代币存入源链上的智能合约;
  2. 然后,dApp通过API将充值交易哈希发送到后端服务器;
  3. 交易哈希需要经过服务器的多次验证,如果被认为合法,则签名者会签署一条消息,并将签名通过API发回到用户界面;
  4. 收到签名后,dApp会对其进行验证,并允许用户从目标链中提取代币。

后端服务器必须确保其处理的充值交易是真实发生而并非伪造的。该后端服务器会决定用户是否可以在目标链上提取代币,因此成为首当其冲的攻击目标。

后端服务器需要验证交易发起事件的结构,以及发起该事件的合约地址。如果忽视后者,攻击者就可能会部署恶意合约,来伪造与合法充值事件结构相同的充值事件。

如果后端服务器不验证哪个地址发起了该事件,它就会认为这是有效交易,并且签署消息。攻击者就可以向后端服务器发送交易哈希,绕过验证,使其从目标链中提取代币。

不当的原生代币处理

跨链桥采用不同的方法来处理原生代币和效用代币。比如,在以太坊网络上,原生代币是ETH,大多数效用代币都符合ERC-20标准。

如果用户打算把自己的ETH转移到另一条链,必须先将其存入跨链桥合约。为此,用户只需将ETH附到交易中,即可通过读取“msg.value”交易字段来检索ETH的数量。

存入ERC-20代币与存入ETH有很大区别。要存入ERC-20代币,用户必须先允许跨链桥合约使用他们的代币。

在他们批准并将代币存入跨链桥合约后,合约将用 “burnFrom()”函数销毁用户的代币,或用“transferFrom()”函数将用户的代币转移到合约中。

要区别是哪种操作,可以在同一个函数中使用if-else语句。或是创建两个单独的函数来处理每种场景。由于处理方式不同,如果用户尝试使用ERC-20充值函数来存入ETH,那么这些ETH可能会丢失。

在处理ERC-20充值请求时,用户通常提供代币地址作为输入参数传递给充值函数。这会构成重大风险,因为在交易过程中可能会发生不可信的外部调用。

使用白名单来只包含跨链桥支持的代币,是把风险降到最低的常见做法。只有列入白名单的地址会作为参数传递。这样可以防止外部调用,因为项目团队已经过滤了代币地址。

但是,当跨链桥处理原生代币跨链传输时,也有个麻烦,因为原生代币没有地址。原生代币可以使用一个特殊的地址来代表,即“零地址”(0x000… 0)。

但这样做存在一个问题,如果未正确实现白名单验证逻辑,使用零地址传递给函数可能会绕过白名单验证。

当跨链桥合约调用“TransferFrom”将用户资产转移到合约时,对零地址的外部调用会返回false,因为零地址中没有实现“transferFrom”函数。

但是,如果合约没有正确处理返回值,交易仍可能继续发生。这就会为攻击者创造机会,使其不用向合约转移任何代币就能执行交易。

配置错误

在大多数区块链桥中,有一个特权角色负责将代币和地址列入白名单或黑名单,分配或改变签名者,以及其他关键配置。

确保所有配置准确无误非常关键,因为看似微不足道的疏忽也可能导致重大损失。

推荐阅读