Chapter 9-2: セキュリティを高めるための手法

blockchain.akifumifukaya.net

上記の記事で、コントラクトへの攻撃手法の説明をしました。

ここではセキュリティを高めるライブラリであるOpenZeppelinを紹介します。

OpenZeppelin

OpenZeppelinは、Solidityでセキュアなスマートコントラクトを作成する目的で作られた、基本的なスマートコントラクトのフォーマットを提供するライブラリ群です。

ERC20準拠トークン、クラウドセール、オーナー権限などのさまざまな雛形が用意されています。

スマートコントラクトはチューリング完全で自由度が高く、任意のプログラミングを作成して実行することが可能です。

しかし、自由度が高い反面、予期せぬ動作を発生させることにも繋がります。

OpenZeppelinに沿って作成することで、不具合や抜け漏れなどの障害を抑えることが可能になります。

開発元であるZeppelin Solutionsは、セキュリティに関する具体的な設計指針を「(Onward with Ethereum Smart Contract Security)https://blog.zeppelin.solutions/onward-with-ethereum-smart-contract-security-97a827e47702」として公開しています。

コントラクトの失敗は可能な限り早く失敗させ、かつ隠さない

assert, requireなどを使用して、チェックすることを心掛けましょう。

送金を引き出す機能を実装する

送金をコントラクト側で実行すると、fallback関数内で悪意のある処理を実行されてします。

Pull Payment Systemで実装しましょう。

状態確認、影響確認、動作の各機能に分割して実装する

「可能な限り早く失敗する」を実現する設計にも繋がります。

関数を実行する前に、関数を実行するための条件が揃っていることを確認します。

条件が揃っていなかったら処理を終了させます。

続いて、状態を更新し、更新が実行されなかったら場合、処理を中断してトランザクション前の状態に戻します。

最後に他のコントラクトやユーザーへのメッセージを返します。

EVMプラットフォームの制限に注意する

EVMプラットフォームの制限を把握しておきましょう。

配列が255以上になると、配列のループは必ずGasが枯渇して終了します。

また、開発者が予期しない操作をするのがユーザーです。

予期しない値も入力される前提にして、明示的に最適な型を指定しましょう。

EVMの仕様上、コールスタックにも1024回までという限界があります。

関数の処理にどの程度のスタックが必要なのか、常にコールスタックの限界を意識しましょう。

テストを書く

テストは必要以上にやっても損はありません。

リファクタリングや機能追加でも手助けになります。

テストは書くようにしましょう。

バグ報告機能と緊急停止機能を実装する

どんな開発者でもすべての脆弱性を把握することは困難でしょう。

バグを発見したユーザーに、報酬トークンを対価として支払ったり、コミュニティ内で何らかのインセンティブを付与するなど、報酬を払う仕組みを用意しておくと、バグ発見率が上がるはずです。

また、コントラクトは上書きできないので、緊急度が高いバグを発見した際は一時的にメンテナンスモードにするなどの要望もあります。

非常時のためにコントラクトをデプロイしたオーナーは、いつもでプログラムを停止状態にできる機能を実装しておくと、万が一のときに甚大な被害を回避することができます。

大量の資金を失うリスクを避けるため、デポジットの制限機能を用意する

コントラクト上に多くの資産を保有しているプログラムが狙われやすいです。

不用意に攻撃対象と認識されないために、コントラクトに預けるユーザーの資源量を制限する機能を実装するのは良い試みです。

ファイルを独立させてシンプルな実装にする

一般的なプログラムと同様に、モジュール構成でシンプルな実装を心掛けましょう。

シンオウるに小さくコードを記述することで、開発上の理解の向上に繋がります。

関数は短く、コードの依存関係を最小限にすることが重要です。

また変数や関数は理解しやすい命名に心掛けましょう。

ゼロから書き上げずに、OpenZeppelinのフォーマットを利用する

OpenZeppelinは、安全なコントラクトを作成するベストプラクティスを提供しています。

実績があり安全なコードがある場合は再利用することも選択肢の1つです。

Mythril

MythrilはSolidity用のセキュリティ分析ツールです。

コンパイル後のコードやSolidityのファイルから脆弱性を検知できます。

GethにデプロイしたコントラクトのアドレスをMythrilで指定することで、分析診断が可能です。

アセンブルしてスタックしたオペレーションを直接確認することができ、処理フローをグラフで表示することもできます。

スマートコントラクトの開発には念には念を入れたテストを実施し、攻撃は起き得るものと認識しておきましょう。

攻撃が発生した場合には、コントラクトを緊急停止して、セキュリティ分析ツールで調べるなどの準備をしておきましょう。