この5つの脆弱性の中で、現代の監査技術によって比較的少なくなったものはどれですか?
リエントランシー攻撃とアクセス制御の不備という比較的基礎的な脆弱性の2種類は、現在では成熟した自動静的解析ツールで迅速にスキャンし検出できるようになっており、業界も大量の既知の事例を蓄積して標準的なチェックリストを形成している。正規の監査プロセスを経たほとんどのプロトコルは、理論上ローンチ前にこの種の「教科書レベル」の脆弱性を排除できるはずであり、実務上もこの2種類の脆弱性による重大事件は近年確かに減少傾向にある。
対照的に、複雑なロジック設計の欠陥や複数プロトコル間のやり取りによって生じる問題は、監査技術が継続的に進歩していても依然として完全に根絶することが難しい種類である——この種の問題はしばしば単一のコントラクト内部の誤りではなく、それぞれ単独では正しく見える複数の独立したシステムが組み合わさって初めて浮上する予期しない挙動だからだ。この種の問題の検出は監査人がプロトコルのエコシステム全体をどれだけ深く理解しているかに大きく依存し、単純なコードスキャンで解決できるものではない。これが、近年の重大な攻撃事件でこうした複雑な相互作用による事例の方が、基礎的な脆弱性よりもむしろよく見られる理由でもある。
ある脆弱性が理論上基礎的で発見しやすいはずなのに、なぜプロトコルはそれによって攻撃を受けてしまうのですか?
いくつかの実際的な理由がある:時間と予算の圧力——一部のプロジェクトは市場での先行を争うために監査プロセスを圧縮したり、コアコントラクトのみを監査して周辺モジュールを見過ごしたりすることがある;アップグレードや変更後の再監査の欠如——多くの攻撃はプロトコルがローンチ後に新機能を追加したりパラメータを変更したりする段階で発生する。元の監査報告書は最初のローンチバージョンのみをカバーしており、その後の変更が同期して監査されていなければ、新しいコードは検証を経ていない状態に完全にさらされることになる;監査自体の品質のばらつき——「監査済み」を謳うすべてのプロトコルが同じ水準の監査機関に依頼しているわけではなく、一部の監査は品質にばらつきがあり、基礎的な脆弱性すら本当には発見されていない可能性がある。
これが、監査報告書を確認する際、「監査を受けたかどうか」を確認するだけでなく、さらに監査対象のコードバージョンが現在稼働中のバージョンと一致しているか、監査機関の過去の実績と評判はどうかを確認する必要がある理由でもある。これらの詳細は「監査バッジがあるかどうか」という表面的な情報よりもしばしば参考価値が高い。
一般ユーザーは自分でブロックチェーンエクスプローラーを使って、あるプロトコルのコントラクトに明らかなアクセス制御リスクがないか簡単に確認できますか?
ある程度は可能である。完全なコードを理解する必要はないが、いくつかの基本的なチェックができる:ブロックチェーンエクスプローラーでコントラクトが「オープンソース化され検証済み」(verified)かどうかを確認する。これはコントラクトのソースコードが公開されて読める状態であり、コンパイル後の機械コードだけではないことを意味する;コントラクトがオープンソースであれば、コード内にonlyOwnerやonlyAdminといった権限修飾子が付いた関数がないか検索し、これらの関数が対応する実際の機能が何かに注意する(発行、資金プールからの引き出し、重要パラメータの変更といった機微な操作を含んでいないかなど);同時にこの「owner」や「admin」のアドレス自体が一般的な外部アカウントなのか、マルチシグウォレットなのかを確認する——重要な権限が単一の一般アカウントに集中しており、複数の当事者が共同で署名しなければ実行できないマルチシグの仕組みでない場合、このプロトコルには単一障害点や内部者の不正行為のリスクが存在することを意味する。
これらのチェックはロジックの欠陥やリエントランシー攻撃といった複雑な問題を理解する必要はない(それは確かに専門的な能力が必要だ)が、「権限設計が過度に集中していないか」という比較的理解しやすく、比較的確認しやすいリスク指標を掴む助けになる。
これらの脆弱性の種類には共通の防御哲学がありますか?それとも各々がまったく異なる解決策を必要としますか?
5つの脆弱性の技術的な詳細は異なるが、その背後には共通の防御哲学がある:どの単一の要素も「必ず」期待通りに動作すると信じてはならず、「もしそうならなかった」場合のための緩衝をあらかじめ設計しておくことだ。リエントランシー攻撃への防御は、外部呼び出しを行う前に先に状態を更新することである(外部呼び出しの間に何が起きても、状態はすでに正しい状態になっている);整数オーバーフローへの防御は、境界を自動的にチェックしラップアラウンドできない安全な数学ライブラリを使用することである;アクセス制御への防御は機微な権限を単一アカウントではなくマルチシグの仕組みに委ねることである(単一の保有者が絶対にミスをしたり悪意ある行動を取らないとは信じない);オラクル操作への防御は単一の価格ソースに依存しないことである(どの一つのデータソースも必ず正確だとは信じない);ロジックの欠陥への防御は、様々な極端なシナリオをシミュレートするテストを通じて、「ユーザーが自分の想定していなかった方法でこれらの機能を組み合わせて使うかもしれない」と積極的に仮定することが必要となる。
この共通の哲学は一文にまとめられる:優れたスマートコントラクト設計とは、すべてがうまくいくと仮定することではなく、どこかで必ず何かが間違うと仮定し、間違った際の損失を止めるメカニズムをあらかじめ設計しておくことである。
あるプロトコルが「スマートコントラクトの脆弱性により攻撃を受けた」と発表するのを見ると、ほとんどの非エンジニアのユーザーは「コントラクトが壊れて、お金が盗まれた」というレベルまでしか理解できず、この事件が偶発的なものなのか、それともこのプロトコル全体のエンジニアリング品質に構造的な問題があるのかをさらに判断することは難しい。いくつかの最も一般的な脆弱性の種類の背後にあるロジックを理解することは、コード自体を読める必要はなく、プロトコルの安全性を判断する基礎的な枠組みを構築できる。
リエントランシー攻撃はDeFi史上最も古く、最も典型的な脆弱性の種類である。引き出しのプロセスを想像してみてほしい:コントラクトはまずあなたの残高記録を差し引き、その後お金をあなたに転送すべきだ。しかしコードの順序が逆になっている場合——先にお金を転送し、その後で残高記録を更新する——攻撃者は「お金はすでに送金されたが、残高記録はまだ更新されていない」というその隙を突いて、システムがまだ残高をゼロにしていないうちに引き出し関数を再度呼び出すことができ、実質的に攻撃者が同じ預金を何度も繰り返し引き出せてしまう。これはATMがまだ取引をデータベースに書き戻していないうちに、あなたが駆け込んで引き出しボタンを何度も連打するようなものだ。2016年のThe DAO事件はまさにこの攻撃パターンであり、約6,000万ドル相当のイーサが流出する結果となった。
コンピューターが数字を保存する空間には限りがあり、ある変数がある最大値までしか保存できない場合、計算結果がこの上限を超えると、システムは「エラー」を表示するのではなく、直接「ラップアラウンド」して非常に小さい、あるいはゼロの数字になることがある(あるいは逆に、小さい数字から引きすぎて極めて大きな数字になる)。3桁までしか表示できないカウンターを想像してほしい。999まで数えてさらに1を足すと、画面には1000ではなく、ラップアラウンドして000と表示される。もし攻撃者が意図的にこの種の「数字のラップアラウンド」の状況を作り出せれば、コントラクトに実際には存在しない大量の残高がまだ利用可能だと誤認させられる可能性がある。
ほとんどのコントラクトは「管理者のみ実行可能」な機微な機能を設計している。例えば取引の緊急停止、重要パラメータの変更、さらにはトークンの直接発行などだ。アクセス制御の不備とは、本来身分を制限すべきこれらの関数が、コード内で身分確認のチェックが漏れていたために、誰が呼び出しても実行できてしまう状態を指す。これはビルの中に「従業員専用」と表示された扉があるのに、ドアノブに鍵を付け忘れており、通りすがりの誰もが直接押し開けて入れてしまうようなものだ。この種の脆弱性は通常、複雑なロジック設計の問題ではなく単純な見落としに起因し、理論上はコードレビューの段階で比較的発見しやすい種類のはずだが、実務上は依然として時折発生している。
もしコントラクトが担保が十分かどうか、清算を発動すべきかどうかの判断を完全にある価格ソースに依存しており、その価格ソースが攻撃者によって巨額の取引で瞬時に吊り上げられたり押し下げられたりできる場合、攻撃者は「一時的だが連鎖反応を引き起こすのに十分な」偽の価格を作り出せる。これは、ある店が簡単に調整できる一台の体重計だけを使って客がいくら支払うべきかを判断しているようなものだ。誰かがこっそりと体重計の針を調整できれば、レジシステムは間違った重さに基づいて会計してしまう。防御方法は通常、単一の即時価格ソースだけに依存せず、複数のソースと相互照合するか、ある瞬間の即時価格ではなく一定期間の平均価格を採用することだ。
これは自動化ツールで発見するのが最も難しい脆弱性の種類である。コード自体にはまったく構文エラーがないかもしれず、各関数を単独で見れば正常に動作しているからだ。問題は全体的なビジネスロジックの設計にある——いくつかの機能が特定の順序で組み合わせて使われると、設計者がまったく予期していなかった結果を生む。これはルールブックの中で各ルールを単独で見れば合理的だが、いくつかのルールを繋げると、誰も想定していなかった脆弱性の経路が導き出せてしまうようなものだ。この種の問題は通常、プロトコルのビジネスロジックを深く理解している人による手動レビューでしか発見できず、監査業務の中で最も経験と想像力が試される部分である。
次にあるプロトコルの脆弱性事件の発表を見たとき、この攻撃がどの種類に近いかを判断してみるとよい:リエントランシー攻撃や整数オーバーフローのような比較的基礎的な脆弱性であれば、チームのエンジニアリングレビュープロセス自体に明らかな欠陥があったことを反映しているかもしれない。複雑なロジック設計の欠陥や複数プロトコル間のやり取りによって生じた問題であれば、比較的厳格なエンジニアリング実践を行っていても、DeFiエコシステムの高度に組み合わせ可能な特性が依然として完全には排除しきれないリスクをもたらすことを示している。この判断であなたがセキュリティの専門家になれるわけではないが、事後検証報告書を読む際に「このプロトコルで問題が起きた」という表面的な理解にとどまらず、より意味のある情報を掴む助けになる。