保障 Solana 生态系统(七)——类型混淆

文章讨论了 Solana 中的类型混淆(Type Confusion)安全问题,重点阐述了其对账户反序列化/序列化的影响以及攻击者进行利用的可能性。

保障 Solana 生态系统(七)——类型混淆

0. 回顾

1. 概述

在上一篇博客中,我们介绍了通用多重签名功能的实现。在本文中,我们将讨论另一个安全问题——类型混淆。

2. 反序列化/序列化

在 Solana 中,程序状态存储在账户中。类型混淆问题发生在账户的反序列化/序列化过程中。程序逻辑通常依赖于数据结构。然而,程序在反序列化/序列化过程中可能无法正确检查账户的类型。这可能会被攻击者滥用,导致意外损失。

3. 代码审查(类型混淆)

下文将通过一个简单的程序来说明类型混淆问题。你可以在此处找到测试代码。

在测试程序中,我们实现了两个数据结构,一个是 User,另一个是 Metadata。它们都记录了一个账户的公钥(不同的账户)。

该程序有三个不同的指令。InitializeUser 指令用于创建 User 账户并设置一个授权账户(即 authority)。类似地,InitializeMeta 指令用于创建 MetaData 账户并设置一个普通账户(即 account)。Test 指令演示了攻击者可以绕过程序的验证逻辑,并利用受控的 MetaData 进行攻击。

我们来逐步分析 Test() 指令。程序确保传入的 User 账户的所有者是程序本身(第 86-89 行)。反序列化后(第 92 行),程序将传入的 authority 账户的公钥与存储在 User 账户中的公钥进行比较。如果不相等,程序将回滚(第 93-96 行)。最后一个检查是确保 authority 账户已签署交易。然而,如果攻击者传入受控的 Metadata 账户,所有检查仍然可以被绕过。原因是程序不会检查账户的类型。它接收一个字节数组并直接将其反序列化为程序中定义的各种类型的结构。

我们部署了测试程序以进行进一步测试,可以在此链接找到。

3.1 发送交易

部署程序后,我们编写脚本按顺序调用程序提供的三个指令。

我们首先调用 InitializeUserInitializeMeta。注意,我们将我们自己的公钥设置为存储在 Metadata 账户中的 account 账户。

test() 函数中,我们将 Metadata 账户作为 User 账户,并将我们自己的账户作为 authority_info 传入(第 347-348 行)。程序将 MetadataUser 结构进行反序列化,所有检查都可以被绕过。

我们发送了交易,可以在这里找到。程序返回成功,这意味着我们使用未经检查的账户类型成功通过了检查。

4. 总结

在本文中,我们介绍了 Solana 中的类型混淆问题。有很多方法可以避免这个问题。例如,我们可以在结构体中添加一个属性来记录账户的类型,并且程序在读取/写入传入账户之前应始终检查类型属性。请继续关注,我们将在后续文章中分享更多内容。

阅读本系列的其他文章:


关于 BlockSec

BlockSec 是一家开创性的区块链安全公司,由一群享誉全球的安全专家于 2021 年创立。公司致力于为新兴的 Web3 世界增强安全性和可用性,以促进其大规模采用。为此,BlockSec 提供智能合约和 EVM 链安全审计服务,用于安全开发和主动阻止威胁的Phalcon平台,用于资金追踪和调查的MetaSleuth平台,以及供 Web3 构建者在加密世界中高效冲浪的MetaSuites扩展。

迄今为止,公司已为 MetaMask、Uniswap Foundation、Compound、Forta 和 PancakeSwap 等 300 多家尊贵客户提供服务,并在两轮融资中从 Matrix Partners、Vitalbridge Capital 和 Fenbushi Capital 等知名投资者那里获得了数千万美元的投资。

官方网站:https://blocksec.com/

官方 Twitter 账号:https://twitter.com/BlockSecTeam

Sign up for the latest updates