Back to Blog

Solanaエコシステムの保護 (4) — アカウント検証

April 1, 2022
6 min read

0. レビュー

1. 概要

前回のブログでは、プログラムのアップグレード方法について説明しました。本稿では、DeFi分野で最も一般的かつ基本的なセキュリティトピックの1つである、アクセス制御に関連する問題について紹介します。

2. 説明

Solanaでは、各プログラムは1つのentrypointをエクスポートし、これはentrypoint!で定義されます。Ethereumとは異なり、クライアントはentrypointとして定義された単一の関数(通常はprocess_instructionと呼ばれる)のみを呼び出すことができます。entrypoint関数は3つのパラメータを受け取ります。それらは、スマートコントラクトのプログラムID、プログラムが操作するアカウント、および命令データです。命令データは、どの命令が呼び出されるかを指定します。以下の図に例を示します。命令データをアンパックすることで、異なる命令(例:Lock、Unlock)が選択されます。したがって、entrypointから到達可能な命令はすべての人に公開されており、指定された命令データで実行できます。

3. アカウント検証

前述のように、プログラムは読み書きに必要なアカウントを受け取ります。この設計により、2つの問題が生じます。読み取られるアカウントについては、アカウントに格納されているデータが信頼できることをどのように保証するか。書き込まれるアカウントについては、特権ユーザーのみがアカウントに書き込む命令を呼び出せることをどのように保証するか。以下に、アクセス制御の問題を説明します。すべてのテストコードはこちらで見つけることができます。

3.1 コードレビュー(PrivilegeOwner)

まず、DoorConfigという2つの構造体を定義します。作成されたdoorを開けることができるのは、door構造体(17行目)で指定されたキーアカウントのみです。ただし、システム状態がロックされている場合、ドアを開けることはできません。これはConfig構造体(81行目)で指定されています。

前述のように、Configアカウントはドアを開けることができるかどうかを指定します。この場合、プログラムには1つのConfigアカウントのみが存在する必要があります。これを実現するために、PDAを使用してConfigのデータを格納します。Configアカウントを初期化した後、is_initialized属性をtrueに設定し、攻撃者によって再度初期化されないようにします(108〜110行目)。

Open()命令はドアを開けるために使用されます。この命令は、開かれるドアアカウント、configアカウント、およびdoorを開けようとするownerアカウントを含むいくつかの В receives. ドアがプログラムのものであること、および設定が有効であることを保証するために、doorアカウントとconfigアカウントの所有者を確認します(204〜205行目)。これにより、悪意のあるユーザーが偽のアカウントを入力するのを防ぎます。これは最初の質問に答えます。読み取られるアカウントが信頼できることを保証するには、アカウントの所有者を確認する必要があります!この場合、所有者アカウントがdoorの実際のownerであるか、さらに重要なことに、命令が所有者によって承認されているかを確認します(217〜219行目)。

validate_owner()関数では、まずこれら2つのアカウントの公開鍵が同じであるかを確認し、次に所有者の署名を確認します。これは2番目の質問に答えます。特権ユーザーのみがopen命令を呼び出すことができることを保証するには、アカウントの所有者と署名者を確認する必要があります。close命令はopenと同様であり、詳細はコードに記載されています。

プログラムをテストネットにデプロイしました。以下のリンクから確認できます。

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

すべてのテストトランザクションを以下に示します。このトランザクションの全体的なプロセスは、Allocate PDA()-> 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 攻撃トランザクション

所有者のチェックと署名者のチェックの重要性を示すために、2つの攻撃シナリオを例として使用します。

最初のシナリオ

最初のシナリオは、「door」の所有者がconfigがロックされている間にドアを開けようとすることです。これを実現するために、別のプログラムで偽のconfigアカウントを作成し、is_lock属性をfalseに設定します。カスタムプログラムのコードを以下に示します。

偽のconfigアカウントを作成するトランザクションを送信します。偽のconfigアカウントの公開鍵は次のとおりです。2MtSrbWp24VjPZQcSUkiWrvNro7qqKemVCsh3Yxc8LTy。

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

偽のconfigアカウントが作成されたら、それをプログラムに渡します(423行目)。

結果は以下のとおりです。ログには「incorrect program id for instruction」と表示されます。これは、configアカウントの所有者はプログラムでなければならないことを意味します。したがって、攻撃者はこのチェックをバイパスできません。

2番目のシナリオ

2番目のシナリオは、ドアがロック解除されている間に悪意のあるユーザーがドアを開けようとすることです。

この場合、実際の所有者アカウントをプログラムに渡します(419行目)。そしてトランザクションを送信します。結果は以下のとおりです。

「Signature verification failed」と表示されます。これは、ドアを開けるには実際の所有者がトランザクションに署名する必要があることを意味します。したがって、2番目の攻撃も失敗します。

4. まとめ

Solanaでは、命令はクライアントまたは他のプログラムによって提供されるさまざまなアカウントに基づいて、指定されたロジックを実装します。したがって、アカウントの適切なチェックは非常に重要です。

この記事では、アカウントを適切にチェックする方法を紹介し、2つの攻撃シナリオを使用してこれらのチェックの重要性を示しました。引き続きフォローしてください。さらに記事が共有されます。

このシリーズの他の記事を読む:


BlockSecについて

BlockSecは、世界的に著名なセキュリティ専門家グループによって2021年に設立された、先駆的なブロックチェーンセキュリティ企業です。当社は、新しいWeb3の世界のセキュリティと使いやすさを向上させ、その大規模な採用を促進することに尽力しています。この目的のために、BlockSecはスマートコントラクトおよびEVMチェーンのセキュリティ監査サービス、セキュリティ開発および脅威のプロアクティブなブロックのためのPhalconプラットフォーム、資金追跡および調査のためのMetaSleuthプラットフォーム、そしてWeb3開発者が仮想通貨の世界を効率的にサーフィンするためのMetaSuites拡張機能を提供しています。

現在までに、当社はMetaMask、Uniswap Foundation、Compound、Forta、PancakeSwapなど300を超える著名なクライアントにサービスを提供し、Matrix Partners、Vitalbridge Capital、Fenbushi Capitalなどの著名な投資家から2回の資金調達ラウンドで数千万米ドルを獲得しています。

公式ウェブサイト:https://blocksec.com/

公式Twitterアカウント:https://twitter.com/BlockSecTeam

Sign up for the latest updates
~$15.9M Lost: Trusted Volumes & More | BlockSec Weekly
Security Insights

~$15.9M Lost: Trusted Volumes & More | BlockSec Weekly

This BlockSec bi-weekly security report covers 11 notable attack incidents identified between April 27 and May 10, 2026, across Sui, Ethereum, BNB Chain, Base, Blast, and Berachain, with total estimated losses of approximately $15.9M. Three incidents are analyzed in detail: the highlighted $1.14M Aftermath Finance exploit on Sui, where a signed/unsigned semantic mismatch in the builder-fee validation allowed an attacker to inject a negative fee that was converted into positive collateral during settlement; the $5.87M Trusted Volumes RFQ authorization mismatch on Ethereum; and the $5.7M Wasabi Protocol infrastructure-to-contract-control compromise across multiple EVM chains.

Newsletter - April 2026
Security Insights

Newsletter - April 2026

In April 2026, the DeFi ecosystem experienced three major security incidents. KelpDAO lost ~$290M due to an insecure 1-of-1 DVN bridge configuration exploited via RPC infrastructure compromise, Drift Protocol suffered ~$285M from a multisig governance takeover leveraging Solana's durable nonce mechanism, and Rhea Finance incurred ~$18.4M following a business logic flaw in its margin-trading module that allowed circular swap path manipulatio

~$7.04M Lost: GiddyDefi, Volo Vault & More | BlockSec Weekly
Security Insights

~$7.04M Lost: GiddyDefi, Volo Vault & More | BlockSec Weekly

This BlockSec weekly security report covers eight attack incidents detected between April 20 and April 26, 2026, across Ethereum, Avalanche, Sui, Base, HyperLiquid, and MegaETH, with total estimated losses of approximately $7.04M. The highlighted incident is the $1.3M GiddyDefi exploit, where the attacker did not break any cryptography or use a flash loan but simply replayed an existing on-chain EIP-712 signature with the unsigned `aggregator` and `fromToken` fields swapped out for a malicious contract, demonstrating how partial signature coverage turns any historical signature into a generic permit. Other incidents include a $3.5M Volo Vault operator key compromise on Sui, a $1.5M Purrlend privileged-role takeover, a $413K SingularityFinance oracle misconfiguration, a $142.7K Scallop cross-pool index injection, a $72.35K Kipseli Router decimal mismatch, a $50.7K REVLoans (Juicebox) accounting pollution, and a $64K Custom Rebalancer arbitrary-call exploit.