仮想通貨の相場は大きく変動する場合がございます。また、レバレッジ取引を行う場合は投資額を上回る損失が生じる可能性がございます。

ブロックチェーン領域において、仮想通貨取引所のビジネスが盛んな一方で、Ethereumのスマートコントラクトを活用したビジネスやPoCが日本でも増えてきています。仮想通貨取引所に関してはサイバー攻撃による不正送金という被害が世界中であいついでいますが、スマートコントラクトにおいても、スマートコントラクトそのものへの攻撃被害もここ数年で発生しています。本記事では、ますます利用が加速していくであろう、Ethereumのスマートコントラクトのためのセキュリティについて、前半は概要、後半はエンジニア向けの内容で整理したいと思います。

1、スマートコントラクトとセキュリティ概観

スマートコントラクトは、あらかじめ設定した条件に合致する取引の申請が発生すると、プログラムにより所定の契約が自動的に実行される仕組みです。証券決済、不動産取引、シェアリングエコノミーなどのさまざまな領域で、適用が検討されています。

テクノロジー観点で言ってしまうと、Ethereumにおけるスマートコントラクトとは、Ethereumのネットワークに参加している各ノード上で実行されるプログラムと解釈いただいて問題ありません。スマートコントラクトは誰でも開発してEthereum上にデプロイして実行することが可能です。

一方で、誰でもそのスマートコントラクトにアクセス可能ということを忘れてはいけません。コンパイルされたプログラムは誰でも閲覧可能ですし、誰でもプログラム内の公開関数を呼び出すことが可能です。言い換えると、攻撃表面が広く、攻撃されるリスクが高いということです。実被害の例をあげると、2016年にはThe DAO事件、2017年にはParityマルチシグウォレット機能の脆弱性をついた事例などがあり、いずれも当時の交換レートで数十億円規模の被害が生じています。

スマートコントラクトを活用したビジネスを展開する場合は、非常に高い金銭的リスクも伴う可能性が高いということを強く意識しなければなりません。

2、スマートコントラクトの脆弱性

スマートコントラクトの脆弱性には大きく分類すると2つあると筆者は考えています。1つはスマートコントラクトならではの脆弱性、2つ目はビジネスロジック不備に起因した脆弱性です。

スマートコントラクトならではの脆弱性には有名なものにReentrancy脆弱性、Transaction-Ordering Dependence、Timestamp Dependenceなどがあり、スマートコントラクト開発者内では、最近ではよく知られている脆弱性です。これらの脆弱性は「Ethereum Smart Contract Security Best Practices」と呼ばれるサイトに整理されています。しかしながら、攻撃方法などが詳細には書いておらず理解するのにはやや難があります。拙書の「堅牢なスマートコントラクト開発のためのブロックチェーン「技術」入門」では、上記サイトで記載されている脆弱性についすべてではないですが、脆弱性の仕組みと攻撃方法についてソースコードレベルで解説していますので、上記サイトで理解できなかった方は参考にしていただければと思います。なお、「スマートコントラクトならではの脆弱性」と表現したものの、整数オーバフローなどの、なにもスマートコントラクトに限らない従来の脆弱性についても、後者のビジネスロジック不備系の脆弱性とわけるために便宜上、こちらに分類するものとします。

ビジネスロジック系の脆弱性について代表されるのものがアクセスコントロールの不備です。上述した、Parityマルチシグウォレットを例にあげます。当該スマートコントラクトは、Ethereumでサポートされていないマルチシグをスマートコントラクトで独自に実現しているものでした。当該スマートコントラクトにはM-of-Nを設定するための関数があるのですが、なんと当該関数がアクセス修飾子をつけ忘れた結果、デフォルトスコープによって、公開関数になっていたため誰でもM-of-Nを設定可能という脆弱性でした。攻撃者が、1-of-1で自身のアドレスを設定することで、当該スマートコントラクト上にデポジットされた Etherを引き出すことが可能だったのです。

3、如何に対策するか?

いずれのケースにおいても、本番環境にデプロイする前に脆弱性を潰しこむことが大切です。

1つ目のケースは自動で脆弱性を検出するツールもあるため、ツールを活用することも有効でしょう。例えば代表的なものに、ConsenSys社が公開しているMythrilというツールがあります。しかし、ツールにも限界があり見つけられないものもあるため、一通りツールを回したあとはマニュアルで確認する必要があります。また誤検知もあるため、ツールが脆弱性だと判断しても、本当に脆弱かどうかの見極めは必要です。

2つ目のケースは残念ながらツールでの検知は不可能だと考えてください。先のParityの件もそうですが、関数が公開関数でよいかどうかは、関数がなんのために存在していてどんなビジネスロジックを実装しているかによって変わってくるため、ツールでは判断できないためです。したがって、すべての関数を洗い出し、中身を理解した上で、公開すべきかどうかというのを判断しなければなりません。公開関数にするにせよ、管理者などの一部のアドレスからの実行のみを想定している場合は、そのようなアクセス制御がプログラム内で実装されていることを確認しなければなりません。注意していただきたいのは、これは自身が作成したプログラムだけに限らないという点です。例えば最近だと、zeppelinのようなライブラリ(スマートコントラクトの集まりだと思ってください)を継承等で利用しながら実装するのが一般的ですが、第三者が開発したものも含めて確認する必要があると筆者は考えます。一方で、Ethereumのスマートコントラクト開発で利用されるSolidityというプログラミング言語は多重継承をサポートしていたりして、依存関係のあるコントラクトを洗い出すのが大変です。著者が作成した、sca2tというツールでは依存関係の可視化、すべてのコントラクトの関数やステートを一覧で出力しますので、このようなツールで全体像を把握すると良いでしょう。

なお、「第三者が開発したものも含めて確認する」というのはビジネスロジック不備系のものだけでなく、スマートコントラクトならではの脆弱性についても言えることです。例えば、zeppelinは一般的にセキュアなライブラリと言われることがありますが、それでも脆弱性がないとは限りません。仮に脆弱性が見つかった場合の責任は利用者にあるということを肝に銘じておきましょう。弊社が所属しているNRIセキュアテクノロジーズのブロックチェーン診断でも、顧客が開発したコントラクトだけではなく、利用しているオープンソースのコントラクトを含めて診断するようにしています。

重要な点として、上記のような対策をしたとしても、それでも脆弱性は見つかるという前提にたつことです。Ethereumのスマートコントラクトは一度デプロイすると、そのプログラムは変更できません。したがって、脆弱性が見つかると打つ手がない、という状況にもなりかねません。そのため、有事の際に、スマートコントラクトを停止するような機能を用意しておくことが重要です。例えば、Circuit Breakers 用の関数を用意しておくなどです。緊急停止ボタンのようなものだと思ってください。処理の詳細を簡単に説明します。コントラクトのステートで、Circuit Breakersのon/offを表現しておきます。そして、関数内の最初の処理で、当該ステータを確認し、onになっていたら以降の処理を行わないようにしておくといったものです。Circuit Breakers用の関数でon/off を設定します。もちろん、Circuit Breakers 用の関数は管理者アドレスのみが実行できるようにしておく必要があります。他にも、ライブラリ用途のコントラクトをデプロして、そのコントラクトを委譲して呼び出だすようにデザインして、ライブラリ側に脆弱性が発見された場合は、新しいコントラクトをデプロイして、呼び出し元のコントラクト内の呼び出し先コントラクトのアドレスを変更できるようにしておく、という考えもありますが、いずれにせよ、コントラクトの改修、デプロイが完了するまでの時間を考えると、Circuit Breakers は必須だと筆者は考えます。

脆弱性が潰しこまれていること、ここまで説明した対策がなされているかを確認するため、デプロイ前に一度専門家にセキュリティ診断を依頼するのも重要です。

4、エンジニアとしての心構え

さて、上述した、Reentrancy脆弱性、Transaction-Ordering Dependence、Timestamp Dependenceやビジネスロジックの不備などは、Solidityが理解できれば、比較的容易に理解できると筆者は考えます。スマートコントラクトは性質上、巨大なプログラムではなく小規模なプログラムになりますし、なにか一つでもプログラミング言語を高いレベルで習得できていれば、Solidityで「ただ動くスマートコントラクト」を開発するのはさして難しくもありません。早い人だと、1-2日もあれば動くスマートコントラクトを実装できるようになると筆者は思います。

しかし、動くスマートコントラクトを実装できるようになり、上述したような比較的理解しやすい脆弱性を理解した程度のレベルではスマートコントラクトのセキュリティは守れません。最近の攻撃コンセプトでは、Ethereumそのものの仕組みを深く理解しておかないと理解できないものもあります。一例として、2018年になって「Ethereum Smart Contract Security Best Practices」に追加された、 Underflow in Depth: Storage Manipulation という脆弱性をあげます。ここで挙げられているソースコードには整数アンダーフローの脆弱性があり、これを悪用することで、本来更新できないはずのステートを更新できるという脆弱性です。整数アンダーフロー自体そのものの理解は容易ですが、それを悪用して「如何に攻撃するか?」というのは、Ethereumの動的配列がストレージでどのように扱われるかと内部処理を深く理解していなければ理解することができません。当該サイトだけでは、その仕組みや攻撃方法の詳細が書かれたおらず理解が難しいと思いますので、別サイトで詳しく解説しておきました。理解できなかった方は英語のサイトですが参考にしてみてください。

Ethereumそのものを深く理解しなければ、高度な攻撃方法の理解はできず、スマートコントラクトの高いセキュリティは実現不可能です。スマートコントラクトの開発者は、Solidityで動くスマートコントラクトが実装できる、代表的な脆弱性について理解しているというレベルではなく、Ethereumそのものを仕様レベルで深く理解し、最新の攻撃コンセプトなどもいち早くキャッチして腹におとしこめるだけのスキルが重要になってくるでしょう。

この記事が気に入ったら
いいね!しよう
最新情報をお届けします

この記事を書いた人:田篭 照博

田篭 照博

「堅牢なスマートコントラクト開発のためのブロックチェーン[技術]入門」「堅牢なシステム開発/運用を実現するための ビットコイン[技術]入門」などの著者である田篭照博氏によるコラム。日本で初めてブロックチェーン診断としてスマートコントラクトのセキュリティ診断サービスを開発・リリースしたブロックチェーンセキュリティの第一人者が最新のセキュリティと脅威動向を紹介します。

主要仮想通貨

国内人気取引所一覧