導入
Solanaプログラムは一度デプロイされると、資金や重要なデータを扱い続けます。ちょっとしたチェック漏れが、そのまま資金流出につながることもあります。この章の最後に、Solana開発でよく起きる脆弱性のパターンと、Anchorがそれをどう予防するかを整理します。
説明
代表的な脆弱性と、対応するAnchorの防御策を対応表にまとめます。
| 脆弱性 | 何が起きるか | Anchorでの対策 |
|---|---|---|
| 署名者チェック漏れ | 本人の許可なく、他人のアカウントを操作する命令が実行できてしまう | Signer<'info> 型を使う。Anchorが自動で is_signer を検証する |
| 所有者チェック漏れ | 別のプログラムが作った偽のアカウントを、正規のデータのように読み込ませられる | Account<'info, T> 型を使う。所有者プログラムIDとディスクリミネータをAnchorが自動検証する |
| 整数オーバーフロー/アンダーフロー | 残高やカウンタの計算が桁あふれし、意図しない大きな値・負の値になる | checked_add/checked_sub/checked_mul を使う。またCargoの overflow-checks = true でオーバーフロー時にpanicさせる |
| PDA/アカウントの取り違え | 似た構造の別のアカウントを渡され、想定外のデータとして処理されてしまう | seeds/bump 制約でPDAの導出元を検証し、has_one で関連アカウントの整合性を検証する |
| 任意アカウント注入(arbitrary account injection) | 命令が期待していない種類・所有者のアカウントを渡され、想定外の処理に使われる | Account<'info, T> や Program<'info, T> など具体的な型で受け取り、Anchorに型ごと検証させる(AccountInfoのまま無検証で使わない) |
flowchart TB
Req[クライアントからの命令呼び出し] --> Q1{署名者は正しいか?}
Q1 -- Signer型で検証 --> Q2{所有者プログラムは正しいか?}
Q2 -- Account型で検証 --> Q3{PDA/関連アカウントは正しいか?}
Q3 -- seeds/bump/has_oneで検証 --> Q4{計算にオーバーフローはないか?}
Q4 -- checked_*系関数で検証 --> OK[命令を実行]
整数の計算だけは、Anchorの型やアカウント制約では防げず、開発者自身が意識してチェック付きの演算を使う必要がある点に注意してください。
// 危険: リリースビルドではオーバーフローが検出されないことがある
account.balance = account.balance + amount;
// 安全: オーバーフロー時はErrへ
account.balance = account.balance
.checked_add(amount)
.ok_or(ErrorCode::Overflow)?;
Anchorは「よくある間違いを型で防ぐ」フレームワークですが、「型で表現しきれないロジックの誤り」までは防いでくれません。制約が何を検証しているかを理解したうえで、「このアカウントは本当にこの型・この所有者であるべきか」「この計算はあふれないか」を、自分の頭で確認する習慣が最後の防波堤になります。
演習
第7章レッスン27の演習で考えた「has_one = owner を外すとどうなるか」を、この表のどの脆弱性のパターンに当てはめられるか答えてみましょう。
ヒント1を見る
「他人の greeting_account を自分のものとして更新できてしまう」という状況でした。
ヒント2を見る
これは「PDA/アカウントの取り違え」または「任意アカウント注入」に分類できます。