返回博客

保障Solana生态系统安全(4)— 账户验证

2022年4月1日
阅读约 6 分钟

0. 回顾

1. 概述

在上一篇博客中,我们讨论了如何升级程序。本文将介绍与访问控制相关的问题,这是 DeFi 领域中最常见、最基础的安全主题之一。

2. 指令

在 Solana 中,每个程序导出一个单一的 entrypoint,它通过 entrypoint! 定义。与以太坊不同,客户端只能调用一个定义为入口点的函数,通常称为 process_instruction。入口点函数接收三个参数:智能合约的程序 ID、程序将操作的账户,以及指令数据。指令数据指定了将调用哪条指令。下图展示了一个示例。通过解包指令数据,可以选择不同的指令(例如 Lock、Unlock)。因此,从入口点可访问的指令对所有人公开,并可通过指定的指令数据执行。

3. 账户验证

如前所述,程序接收需要读取或写入的账户。这种设计带来了两个问题。对于需要读取的账户,如何保证存储在账户中的数据是可信的?对于需要写入的账户,如何保证只有具有权限的用户才能调用指令进行写入?下面我们将说明访问控制问题。所有测试代码可在此处找到。

3.1 代码审查(PrivilegeOwner)

我们首先定义了两个结构体:DoorConfig。只有在结构体 door 中指定的 key 账户(第 17 行)才能打开已创建的 door。然而,当系统状态被锁定时,门无法打开,这由结构体 Config(第 81 行)指定。

如前所述,Config 账户指定了门是否可以被打开。在这种情况下,程序中应该只有一个 Config 账户。为此,我们使用 PDA 来存储 Config 的数据。初始化 Config 账户后,我们将属性 is_initialized 设置为 true,以防止攻击者再次初始化(第 108 行 - 第 110 行)。

指令 Open() 用于打开门。该指令接收多个账户,包括要打开的门账户、config 账户以及旨在打开 doorowner 账户。为了保证门属于该程序且配置有效,我们检查 door 账户和 config 账户的所有者(第 204 行 - 第 205 行)。这可以防止恶意用户提供伪造账户。这回答了我们的第一个问题——要保证被读取的账户是可信的,我们需要检查账户的所有者!请注意,只有 door 账户的所有者才能打开门。在这种情况下,我们检查 owner 账户是否是 door 的真正 owner,更重要的是,检查该指令是否经过所有者授权(第 217 行 - 第 219 行)。

在函数 validate_owner() 中,我们首先检查这两个账户的公钥是否相同,然后检查所有者的签名。这回答了第二个问题——要保证只有具有权限的用户才能调用 open 指令,我们需要检查账户的所有者和签名者。close 指令与 open 类似,详细信息可在代码中找到。

我们已将该程序部署在测试网上,可通过以下链接查看。

https://explorer.solana.com/address/2Q7FFMWCthBvc6ubLQRx9TRswvaimmd66VaCAfHwsYuC?cluster=testnet

所有测试交易如下所示。此交易的完整流程为 AllocatePDA()-> InitializeDoor()-> InitializeConfig()-> Unlock() -> Open() -> Close()

https://explorer.solana.com/tx/2X9CyMrHTNEvbzXTE95gem2j8spnvsQsabFeSpV8hiNpYjiQPPzLRqt5KN86ZYRjnQvydvs7y5eUjJK7no8knDhk?cluster=testnet
https://explorer.solana.com/tx/2XfVWiXeQeHbpqAEYm3AH2RU6hunnqtr155EC4EAM5Bq9VVZNP6QocAav9cPjEQdJFcQrbsSSxiKadr4HPMov8pz?cluster=testnet
https://explorer.solana.com/tx/5Em41sg7yFXeNpnEJnhUQJanfLWKwjMqiBeNAqEEzFrSN9P8zKKafcv5F7RKT2pseB171qeoa8Uz4fKgazzayCnW?cluster=testnet
https://explorer.solana.com/tx/2PMtzpSgjnKDLGmRWBdUSFBPimWnudCPekUYbWzPzokENFYa4N4ab4HCtynfGrzswFPTgGYKHU8PccUMHv3mXHkR?cluster=testnet
https://explorer.solana.com/tx/3kviP9MqkWGMV4yA7k7yPQ5BGfXmcYLcctmY1u2D7n56eT1nx8jMtDumkUNJy8yA3KkmzrmfQLjqpigc8ehGZzBN?cluster=testnet
https://explorer.solana.com/tx/38iEaJBzuGMLbfcszdVB8pkniezH8JrA3XGq7JdADZTQ4hNQC82GSTUA2bmcypdVy3t7htWnUzkZ4F8EakmNvqz8?cluster=testnet

3.2 攻击交易

为了说明所有者检查和签名者检查的重要性,我们以两种攻击场景为例进行说明。

第一种场景

第一种场景是"门"的所有者在 config 被锁定时尝试打开门。为此,我们在另一个程序中创建一个伪造的 config 账户,并将属性 is_lock 设置为 false。自定义程序的代码如下所示。

我们发送交易来创建伪造的 config 账户,伪造 config 账户的公钥为:2MtSrbWp24VjPZQcSUkiWrvNro7qqKemVCsh3Yxc8LTy。

https://explorer.solana.com/tx/2qSyrL5gdQXmgGCFzmzMm1StFQRkDgWpss9A9jV11q2fgDGM5C1XRuXvbX1N5Dt3q2pRqnmyXHVtXGF5dqadAzpJ?cluster=testnet

一旦伪造的 config 账户创建完成,我们将其输入程序(第 423 行)。

结果如下所示,日志打印出 incorrect program id for instruction,这意味着 config 账户的所有者必须是该程序。因此,攻击者无法绕过此检查。

第二种场景

第二种场景是恶意用户在门未锁定时尝试打开门。

在这种情况下,我们将真实的 owner 账户输入程序(第 419 行)并发送交易。结果如下所示。

日志打印出 Signature verification failed,这意味着真正的所有者必须对交易进行签名才能打开门,因此我们的第二次攻击同样失败。

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

订阅最新动态
Web3攻击面:渗透测试概览

Web3攻击面:渗透测试概览

加密机构承载所有传统攻击面,并叠加资金处理链。本文提供系统的实用抽象:应用、授权与签名、区块链交互、基础设施四组件模型,说明各自职责、代表实现及继承的攻击面,并将web3特有覆盖细分为五大攻击面:生产与自动化运维、签名意图、审批与提现链、资金逻辑及链上交易与已部署合约。

损失约2300万美元:Cosmos EVM与Moonwell遭利用攻击 | BlockSec Weekly
Security Insights

损失约2300万美元:Cosmos EVM与Moonwell遭利用攻击 | BlockSec Weekly

在报告期(2026/08/22-2026/08/30)内,我们统计5起区块链安全事件,损失约2270万美元;Tectonic被盗约7400万-1.195亿美元,因Cronos回滚至攻击前状态而多数被抹除。重点是六链Cosmos EVM漏洞系列(实现约570万美元),经TAC Chain溯源,共享余额同步漏洞串联下溢与上溢耗尽质押池。报告还分析了Moonwell的抵押品核算与预言机价格操纵组合攻击、Tectonic的预言机价格与凭证代币汇率操纵低流动性抵押品、Ajna清算业务逻辑缺陷,以及Solana上的Rain Card Contract Exploit Series(Ed25519签名验证绕过,涉及Avici、Tria等)。

什么是区块链渗透测试?定义与边界
Security Services

什么是区块链渗透测试?定义与边界

区块链渗透测试尚无公认定义,常与审计、扫描、赏金测试混淆。本文提出工作定义:在约定范围与规则下,对运行系统进行对抗性实测,验证可利用路径与控制链;并指出web3新增的资金处理威胁模型,其关键组合缺口在链下到链上的交接。随后梳理该链条的五项可测能力,并将相关目标分流至代码审计、钱包安全审计、web3安全测试、扫描与赏金测试。