Open1
スマートコントラクトのセキュリティメモ
コントラクトのセキュリティの知識も入れたかったので調べた。外部コントラクトを呼び出すことに起因する脆弱性が多い印象。
スマートコントラクトのセキュリティメモ
リソース
- Security | ethereum.org
- Solidity by Example | 0.8.3
- Known Attacks - Ethereum Smart Contract Best Practices
やること
- スマートコントラクトのセキュリティ関連のキャッチアップ
メモ
- スマートコントラクト におけるセキュリティは適切な設計と開発プロセスの時点で始めないといけない
- ここでいう開発プロセスとは?
- さらに航空産業で長年培われた品質管理プロセスもソフトウェアのレビューに活かせるだろうとのこと
代表的な攻撃手法
- Re-entrancy(リエントラント)
- スマートコントラクトが外部のスマートコントラクトを呼び出してるいる時はメモリの状態とプロセスを一時停止させてしまう仕様(再代入可能)とdefault fallback functionの仕組みを突いて、脆弱性のあるスマートコントラクトから攻撃者のガス代がなくなるまでETHを無限に引き出し続けることができてしまう攻撃
- 被害者に攻撃者の口座に預金命令 -> 攻撃者から同額を引き出し命令 -> 被害者からの同額を送金 -> その送金をフックに攻撃者のdefalt fallback functionが起動 -> 再び攻撃者からの引き出し命令が実行 -> 被害者からの送金 ....
- 対策
- 攻撃者への送金前に攻撃者の預金を0にしてから送金する
-
msg.sender.call.value
を使わないでsend
やtransfer
を使う - そもそもuntrustedなコントラクトの実行やそうしたコントラクトへETHの送信をしないように設計すれば防げる
- 再エントラシー攻撃とは何ですか?
- スマートコントラクトが外部のスマートコントラクトを呼び出してるいる時はメモリの状態とプロセスを一時停止させてしまう仕様(再代入可能)とdefault fallback functionの仕組みを突いて、脆弱性のあるスマートコントラクトから攻撃者のガス代がなくなるまでETHを無限に引き出し続けることができてしまう攻撃
- Front-Running(フロントランニング)
- 主に取引所で注文のtransactionが成立する前のプールされた情報を先んじて読み取り、先の注文よりも先に自分のtransactionを実行させようとすること。
- 元々は金融取引における用語。
- 攻撃者は被害者のcallに追従してガス代を引き上げたり被害者のコントラクトの実行を遅らせたりする
- 対策
- 時間やトランザクションの順番に起因して有利になる仕組みを無くすること
- 例えばfirst order オークション等になりうるものなど
- トランザクションを見えないようにすること(Commit and Reveal Scheme)
- 時間やトランザクションの順番に起因して有利になる仕組みを無くすること
- Timestamp Dependence
- タイムスタンプの偽造
- 対策
- Oracleを使って検証
- Integer Overflow and Underflow
- 数値のオーバーフローやアンダーフローによる問題
- 対策
- DoS with Failed Call
- 外部呼び出しのコントラクトを意図的に失敗させて無限ループを起こしDoSを引き起こす攻撃
- 対策
- 複数のコントラクトの呼び出しを控える
- 外部コントラクトの呼び出し失敗時の処理を書く
- DoS with Block Gas Limit
- ガス代limitを超えた場合にtransactionが失敗することを利用した攻撃
- Insufficient gas griefing
- contract内でのsub contract(or function)の実行に必要なガス代が足りずにtransaction全体を失敗もしくは再実行させてしてしまう嫌がらせ
- 対策
- sub contractの方でガス代の検証を行う
- 信頼したsub contractのみ実行するようにする
- Forcibly Sending Ether to a Contract
- selfdestructメソッドを使うとmessage callを使わずにether送れる。これを悪用して
require(msg.value >= 0)
やassert(msg.value == 0)
のようなguard句をすり抜けて本来意図していなかった処理を実行可能にさせること。 - 関連
- selfdestructメソッドを使うとmessage callを使わずにether送れる。これを悪用して