本文是对Avalanche Warp Messaging协议的一次安全审计,发现该协议缺乏内置的重放攻击预防和目标链验证机制,存在潜在的拒绝服务风险。此外,代码中存在结构体内存布局效率低下和不必要的空签名赋值等问题。审计报告肯定了该协议设计的简洁性和代码质量,并强调了开发者在构建跨链消息传递应用时需要考虑安全性。
本次审计是在 Warp Messaging 投入生产使用之前进行的。任何已发现的问题均未影响 Warp Messaging 的生产实例。 TypeDeFiTimelineFrom 2023-10-02To 2023-10-27LanguagesGoTotal Issues3 (0 resolved)Critical Severity Issues0 (0 resolved)High Severity Issues0 (0 resolved)Medium Severity Issues0 (0 resolved)Low Severity Issues1 (0 resolved)Notes & Additional Information2 (0 resolved)
我们审计了 ava-labs/subnet-evm 仓库,commit ID 为 c354ad6。
审计范围包括以下合约:
contracts
├── warp
│ ├── aggregator
| │ ├── aggregation_job.go
| │ ├── aggregator.go
| │ ├── network_signature_backend.go
| │ └── signature_job.go
│ ├── handlers
| │ ├── stats/stats.go
| │ └── signature_request.go
│ ├── payload
| │ ├── addressed_payload.go
| │ ├── block_hash_payload.go
| │ └── codec.go
│ ├── validators
| │ └── state.go
│ ├── backend.go
│ ├── warp_client_fetcher.go
│ ├── warp_client.go
│ └── warp_service.go
└── x/warp
├── config.go
├── contract.abi
├── contract.go
├── contract_warp_handler.go
└── module.go
Avalanche Warp Messaging 是 Avalanche 网络内跨子网通信的基础层。Warp 协议旨在建立不同 Avalanche 子网之间安全且可验证的消息传递。
Warp 利用 BLS 多重签名和加权验证器集来提供高效且安全的通信层。每个子网的验证器集都在 Avalanche P 链上建立索引。当验证器加入子网时,会记录其 BLS 公钥,这使得 P 链能够跟踪验证器集。
Warp 中的消息使用特定的序列化格式,其中包括诸如 networkID
、sourceChainID
和任意 payload 之类的字段。消息首先通过与 Warp 预编译合约交互在源链中创建,并将未签名的 Warp 消息作为事件发出。然后,由中继者来获取这些未签名的消息,并获得足够多的单个验证器的签名,直到达到目标链所需的 stake 阈值。一旦获得足够的签名,中继者将在单个聚合的 BLS 签名中聚合 BLS 签名以生成签名消息,以及一个指示包含哪些验证器签名的位集。
签名消息以及验证器的位集被编码为谓词,并包含在事务的访问列表(EIP-2930)中,该事务被提交到接收链以进行验证和处理。如果谓词编码和 BLS 聚合签名有效,则接收链将能够通过预编译接口访问该消息并进行相应处理。
Warp 协议本质上不提供防止重放攻击的机制。在重放攻击中,恶意行为者可以重新发送先前发送的有效消息,从而可能在接收区块链上引起意外的副作用或状态更改。预防重放攻击的责任留给了实现。因此,开发人员和系统架构师必须意识到此限制,并主动采取其他措施来减轻重放攻击的风险。
Warp 不包括内置的检查或约束来验证消息的目标链。这意味着最初打算从链 A 发送到链 B 的消息可能被 Avalanche 网络内的链 C 或任何其他链接收和处理。此责任也留给了实现。缺乏此功能会带来安全风险,消息可能会被非预期的接收链错误地解释或执行。这可能导致意外的状态更改,甚至资产错配。
免责声明: 请记住,安全审查不能替代审计,在审计中,代码库会在更深的技术层面上花更多时间进行探索。虽然 OpenZeppelin 尽了最大努力分享任何可能构成问题或需要改进的地方,但我们无法保证所有此类问题都已被检测到。
中继者请求验证器对有效的 warp 消息进行签名。之后,他们聚合来自所有签名者的 BLS 签名,并将包含聚合签名的事务作为谓词编码在 AccessList
中并提交到目标链。
验证器将未签名的 warp 消息存储在持久存储中,此外,还使用两个大小有限的缓存来存储签名和未签名的 warp 消息,这些缓存都会在系统重启时清除。签名仅被缓存,因为验证器的 BLS 密钥可能会在重启期间更改,这将导致同一消息的签名不同,从而使缓存中的签名无效。
鉴于为验证器生成签名消息在计算上开销很大,因此恶意中继者有可能利用缓存限制。这可以通过请求大量 warp 消息的签名来完成,从而超过缓存大小。恶意验证器可以不断循环大量消息,以便验证器不断计算消息的签名,而不能简单地从缓存中返回响应。
这会消耗网络的资源,并可能降低网络的性能或可用性。
考虑设置网络监控并扩展当前的 DoS 防护措施来预防这种情况。
更新: 已知悉,未解决。
代码库中的几个结构体没有进行最佳组织,由于填充和对齐而导致内存浪费。这导致高于不必要的内存使用,这会影响性能和资源利用率:
signatureAggregationJob
:104 指针字节,可以为 40
AggregateSignatureResult
:24 指针字节,可以为 8
Aggregator
:64 指针字节,可以为 32
signatureJob
:56 指针字节,可以为 32
AddressedPayload
:104 指针字节,可以为 32
BlockHashPayload
:40 指针字节,可以为 8
WarpMessage
:18: 112 指针字节,可以为 8
SendWarpMessageInput
:64 指针字节,可以为 8
考虑重新排序 struct
字段,将最大的数据类型放在开头,并将大小相似的字段组合在一起。可以使用 fieldalignment
工具验证对齐方式。这将有助于最大限度地减少填充并优化内存使用。
更新: 已知悉,未解决。
当中继者向节点请求特定未签名 warp 消息的签名时,将调用 OnSignatureRequest
函数。此函数将检索请求的消息 ID 的 BLS 签名。该函数将通过调用 GetSignature
函数 向后端请求签名。如果此函数返回错误,则签名将设置为一个 96 字节的空字节数组。但是,此赋值是不必要的,因为如果未找到未签名的 warp 消息或后端未能对其进行签名,则后端的 GetSignature
函数已将签名设置为了 96 字节的空字节数组。
考虑删除 signatureRequestHandler
结构体的 OnSignatureRequest
函数中空字节数组的赋值。
更新: 已知悉,未解决。
Avalanche Warp Messaging 协议提供了一个简约而强大的设计,可作为未来项目构建跨链消息传递的基础。由于该协议实现仅包含基本要素,因此对于开发人员而言,在构建协议时考虑安全方面至关重要。Ava Labs 已彻底记录了这些安全问题,并且还提供了一个名为 Teleporter 的示例实现,该实现解决了所有这些考虑因素。
在审计过程中,发现全面的审查需要探索超出原始范围的代码库。尽管如此,Ava Labs 团队在沟通方面表现出了非凡的反应能力和效率。该协议的一个突出方面是代码库的高质量。该代码不仅编写良好,而且还展示了对潜在边缘情况的细致理解,这些情况都已得到识别并进行了广泛的记录。
- 原文链接: blog.openzeppelin.com/av...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!