スマートコントラクトのエラーまたはパリティからの新しいセキュリティアラート


11月8日に、 Parityは、マルチシグウォレットの操作を担当するコードに重大なエラーを発表しました。これは、一般にアクセス可能なスマートコントラクトに基づいています。 これは2番目のケースです。 最初のケースは2017年7 月19日に発生し、スマートコントラクトの脆弱性が見つかったため、150,000 ETHが撤回されました( 詳細はHabré )。

問題が何であり、約3億ドルがアクセスできなくなった理由を説明してみましょう。

マルチシグウォレットとは
マルチシグ(自然)ウォレットは、プライベートキーの保護を強化する問題を解決するために作成されました。トランザクションには1つ以上のプライベートキーが必要なためです(一般的な形式ではNキーのうちM)。 3つのキーのうち2つがキーの場合の例:1つのキーはローカルに保存され、1つはクラウドに保存され、もう1つのバックアップは(人里離れた場所に)保存されます。 トランザクションを完了するには、2つのキーが必要です。 ここでもう少し読むことができます。

GitHubユーザーdevops199は、スマートコントラクトkillメソッド(パリティウォレットライブラリ)と呼ばれる、公開されているスマートコントラクトのパブリックメソッドを実験しています。 GitHubの問題#6995
この結果、合計約100万ETH(現在の為替レートで3億ドル)の584個のウォレットが「凍結」されました。つまり、それらからお金を転送する機会が失われました。

コメント付きの画像devops199
画像

技術的には、彼は最初にinitWalletコントラクト初期化メソッドを呼び出しました

  function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized { initDaylimit(_daylimit); initMultiowned(_owners, _required); } 

only_uninitialized修飾子only_uninitialized次のように説明されます

  // throw unless the contract is not yet initialized. modifier only_uninitialized { if (m_numOwners > 0) throw; _; } 

ただし、コントラクトを配置するとき、所有者のリストは初期化されず、 m_numOwners変数は0 m_numOwnersた。 m_numOwnersのすべての操作の履歴は、 ここで表示できます

その結果、 devops199を呼び出すと、 initWalletが契約の所有者になることができdevops199た(ライブラリのスマートコントラクトアドレスでmsg.senderと、所有者msg.sender 、つまりdevops199を持つ通常のウォレットになりました)。

次に、 killを実行して削除するだけで済みます。

  // kills the contract sending everything to `_to`. function kill(address _to) onlymanyowners(sha3(msg.data)) external { suicide(_to); } 

EVMのsuicide操作は、契約を破棄し、残りの残高全体を指定された住所に転送するために使用されます。 同時に、 suicide send操作よりも効果的であり、ブロックチェーンの契約データからスペースを解放するため、負のガス値があります。

マルチシグウォレットのロジック全体は契約に依存していたため、2017年7月20日以降にウォレットを作成したすべての所有者(および7月20日以前に別の脆弱性があったため、これは実際にはすべてのユーザーです)が資金を転送する機能へのアクセスを失いましたパリティウォレットウォレット。 次のEthereumの分岐でのみエラーを修正できますが、もちろんこれは起こりません

ライブラリのスマートコントラクトを公開するときにパリティがkill機能を削除すれば、この問題は簡単に回避できたと思います。 テスト時にのみ有用ですが、ターゲットシステムでは有用ではありません。

このようにして、Parity Walletウォレットと3億ドルの歴史は終わりました。

本番環境に渡す前に、テスト用のコードを削除することを忘れないでください!

Source: https://habr.com/ru/post/J342324/


All Articles