Solidityコンパイラの脆弱性分析と開発者のセキュリティ戦略

Solidityコンパイラの脆弱性解析と対策

コンパイラは現代のコンピュータシステムの基本的な構成要素の一つです。それは、主に人間が理解しやすく、書きやすい高級プログラミング言語のソースコードを、コンピュータの低レベルCPUまたはバイトコード仮想マシンが実行可能な命令コードに変換するコンピュータプログラムです。

ほとんどの開発者やセキュリティ専門家は通常、プログラムアプリケーションコードの安全性に関心を持ちますが、コンパイラ自体の安全性の問題を見落とす可能性があります。実際、コンパイラもコンピュータプログラムの一部であり、安全な脆弱性が存在し、これらの脆弱性は特定の状況下で深刻な安全リスクをもたらす可能性があります。たとえば、ブラウザはJavaScriptフロントエンドコードをコンパイルし解析して実行する過程で、JavaScript解析エンジンの脆弱性により、ユーザーが悪意のあるウェブページにアクセスするときに攻撃者によって脆弱性が利用され、リモートコードを実行され、最終的には犠牲者のブラウザやオペレーティングシステムを制御される可能性があります。

Solidityコンパイラも例外ではなく、Solidity開発チームのセキュリティ警告によれば、複数の異なるバージョンのSolidityコンパイラにはセキュリティの脆弱性が存在します。

Solidityコンパイラの脆弱性

Solidityコンパイラの役割は、開発者が作成したスマートコントラクトコードをEthereum仮想マシン(EVM)命令コードに変換することです。これらのEVM命令コードは、トランザクションを通じてパッケージ化され、Ethereumにアップロードされ、最終的にEVMによって解析されて実行されます。

Solidityコンパイラの脆弱性とEVM自体の脆弱性を区別する必要があります。EVMの脆弱性とは、仮想マシンが命令を実行する際に発生するセキュリティ問題を指します。攻撃者は任意のコードをEthereumにアップロードできるため、これらのコードは最終的にすべてのEthereum P2Pクライアントプログラムで実行されます。EVMにセキュリティの脆弱性が存在すると、Ethereumネットワーク全体に影響を及ぼし、ネットワーク全体がサービス拒否(DoS)を引き起こしたり、攻撃者によって完全に制御される可能性があります。しかし、EVMの設計が比較的シンプルで、コアコードが頻繁に更新されることはないため、上記の問題が発生する可能性は低いです。

Solidityコンパイラの脆弱性とは、コンパイラがSolidityをEVMコードに変換する際に存在する問題を指します。ブラウザなどがユーザーのクライアントコンピュータ上でJavaScriptをコンパイルして実行するシナリオとは異なり、Solidityのコンパイルプロセスはスマートコントラクト開発者のコンピュータ上でのみ行われ、Ethereum上で実行されることはありません。したがって、Solidityコンパイラの脆弱性はEthereumネットワーク自体には影響を与えません。

Solidityコンパイラの脆弱性の主要な危険性は、生成されたEVMコードがスマートコントラクト開発者の期待と一致しない可能性があることです。Ethereum上のスマートコントラクトは通常、ユーザーの暗号通貨資産に関与するため、コンパイラによって引き起こされるスマートコントラクトのバグは、ユーザー資産の損失を招き、深刻な結果をもたらす可能性があります。

開発者や契約監査者は、契約コードの論理実装の問題や、再入、整数オーバーフローなどのSolidityレベルのセキュリティ問題に重点を置くかもしれません。しかし、Solidityコンパイラの脆弱性については、契約のソースコードの論理を監査するだけでは発見が難しいです。特定のコンパイラバージョンと特定のコードパターンを組み合わせて分析する必要があり、初めてスマート契約がコンパイラの脆弱性の影響を受けているかどうかを判断することができます。

! 【Solidityコンパイラの脆弱性解析と対策】(https://img-cdn.gateio.im/webp-social/moments-7d1e882c0b106528437910218bf21f82.webp)

Solidityコンパイラの脆弱性の例

以下は、いくつかの実際のSolidityコンパイラの脆弱性の事例を通じて、その具体的な形、原因、及び危害を示します。

SOL-2016-9 ハイオーダーバイトクリーンストレージ

この脆弱性は、初期のSolidityコンパイラバージョンに存在します(>=0.1.6 <0.4.4)。

次のコードを考えてください:

ソリディティ コントラクトC { uint32 a = 0x1234; uint32 b = 0; 関数 f() public { a += 1; } パブリック ビュー run()関数は (uint32) { を返します。 bを返す; } }

storage変数bは何の変更も受けていないため、run()関数はデフォルト値0を返すべきです。しかし、脆弱性のあるバージョンのコンパイラが生成したコードでは、run()は1を返します。

このコンパイラの脆弱性を理解していないと、一般的な開発者は単純なコードレビューを通じて上記のコードに存在するバグを発見するのが難しいです。これは単なる簡単な例であり、特に深刻な結果を引き起こすことはありません。しかし、b変数が権限検証や資産の記録などに使用される場合、この予期しない不一致は非常に深刻な問題を引き起こす可能性があります。

この奇妙な現象の原因は、EVMがスタック型仮想マシンを使用しているためであり、スタック内の各要素は32バイトの大きさであり、(はuint256変数の大きさです)。一方、基盤となるストレージの各スロットも32バイトの大きさです。そして、Solidity言語のレベルではuint32などの32バイト未満のデータ型をサポートしています。コンパイラーがこのような変数を処理する際、高位を適切にクリアする操作(clean up)を行う必要があります。データの正確性を確保するためにです。上述の状況では、加算が整数オーバーフローを引き起こすとき、コンパイラーは結果の高位に対して正しくclean upを行わず、その結果、オーバーフロー後の高位の1ビットがストレージに書き込まれ、最終的にa変数の後ろにあるb変数を上書きし、b変数の値が1に変更されました。

SOL-2022-4 インラインアセンブリメモリ副作用

次のコードを考えてください:

ソリディティ コントラクトC { function f() public pure は (uint) { を返します。 アセンブリ { mstore(0, 0x42) } uint x; アセンブリ { x := mload(0) } xを返す; } }

この脆弱性は、\u003e=0.8.13 \u003c0.8.15バージョンのコンパイラに存在します。Solidityコンパイラは、Solidity言語をEVMコードに変換する過程で、単なる翻訳にとどまらず、制御フローやデータ分析を深く行い、生成されるコードのサイズを小さくし、実行過程でのガス消費を最適化するためのさまざまなコンパイル最適化プロセスを実現します。このような最適化操作は、さまざまな高級言語のコンパイラでは一般的ですが、考慮すべき状況が非常に複雑であるため、バグやセキュリティ脆弱性が発生しやすいです。

上記のコードの脆弱性は、このような最適化操作に起因しています。ある関数内にメモリの0オフセットのデータを変更するコードが存在するが、そのデータが後続のどこでも使用されない場合、実際にはメモリ0の変更コードを直接削除することができ、ガスを節約し、その後のプログラムのロジックに影響を与えません。

この最適化戦略自体には問題はありませんが、具体的なSolidityコンパイラのコード実装において、そのような最適化は単一のassemblyブロックにのみ適用されます。上記のPoCコードでは、メモリ0の書き込みとアクセスが2つの異なるassemblyブロックに存在しますが、コンパイラは単独のassemblyブロックに対してのみ分析最適化を行いました。最初のassemblyブロックではメモリ0への書き込み後に何の読み取り操作もないため、その書き込み命令が冗長であると判断され、削除されてしまい、バグが発生します。脆弱性のあるバージョンではf(関数は戻り値0を返しますが、実際には上記のコードが返すべき正しい値は0x42です。

) SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

次のコードを考慮してください:

ソリディティ コントラクトC { 関数 f###string( calldata a[1] external は )string memory( { を返します。 abi.decode)abi.encode(a(、)string()を返します。 } }

この脆弱性は、バージョン >= 0.5.8 および < 0.8.16 のコンパイラに影響を与えます。通常、上記のコードが返す a 変数は "aaaa" であるべきですが、脆弱性のあるバージョンでは空の文字列 "" が返されます。

この脆弱性の原因は、Solidityがcalldata型の配列に対してabi.encode操作を行う際に、誤って一部のデータをクリーンアップしたため、隣接する他のデータが変更され、エンコードおよびデコード後のデータが不一致になったことです。

注意すべきは、Solidityがexternal callとemit eventを行う際に、パラメータをabi.encodeを使って暗黙的に処理するため、上記の脆弱性コードが発生する確率は直感的に感じるよりも高くなるということです。

! 【Solidityコンパイラの脆弱性解析と対策】)https://img-cdn.gateio.im/webp-social/moments-c97428f89ed62d5ad8551cdb2ba30867.webp(

セキュリティの提案

Coboブロックチェーンセキュリティチームは、Solidityコンパイラの脆弱性モデルの分析と過去の脆弱性の整理を経て、開発者とセキュリティ担当者に以下の提案を行います。

開発者向け):

  • より新しいバージョンのSolidityコンパイラーを使用してください。新しいバージョンは新たなセキュリティ問題を引き起こす可能性がありますが、既知のセキュリティ問題は通常、古いバージョンよりも少ないです。

  • ユニットテストケースを充実させる。ほとんどのコンパイラレベルのバグは、コードの実行結果が期待と一致しない原因となる。このような問題はコードレビューで発見するのが難しいが、テスト段階で簡単に明らかになる。そのため、コードのカバレッジを向上させることで、このような問題を最大限に回避できる。

  • インラインアセンブリや多次元配列、複雑な構造体のABIエンコーディングとデコーディングなどの複雑な操作は可能な限り避け、明確な要求がない場合は技術を誇示するために言語の新機能や実験的機能を盲目的に使用しないようにしましょう。CoboセキュリティチームによるSolidityの歴史的な脆弱性の整理によれば、ほとんどの脆弱性はインラインアセンブリやABIエンコーダーなどの操作に関連しています。コンパイラは複雑な言語機能を処理する際にバグが発生しやすいです。一方で、開発者が新機能を使用する際に誤った使用法に陥りやすく、安全問題を引き起こすこともあります。

セキュリティ担当者へ:

  • Solidityコードのセキュリティ監査を行う際、Solidityコンパイラがもたらす可能性のあるセキュリティリスクを無視しないでください。Smart Contract Weakness Classification###SWC(に対応するチェック項目はSWC-102: 古いコンパイラのバージョンです。

  • 内部SDL開発プロセスにおいて、開発チームにSolidityコンパイラのバージョンをアップグレードするよう促し、CI/CDプロセスにコンパイラバージョンの自動チェックを導入することを検討できます。

  • しかし、コンパイラの脆弱性について過度に恐れる必要はありません。ほとんどのコンパイラの脆弱性は特定のコードパターンでのみトリガーされ、有効なバージョンのコンパイラでコンパイルされた契約が必ずしも安全リスクを持つわけではありません。実際の安全への影響は、プロジェクトの状況に基づいて具体的に評価する必要があります。

) 実用リソース:

  • Solidityチームが定期的に発表するセキュリティアラート投稿:

  • Solidity公式リポジトリの定期更新バグリスト:

  • 各バージョンのコンパイラバグリスト:

Codeページ右上隅の三角形の感嘆符マークは、現在のバージョンのコンパイラに存在するセキュリティ脆弱性を示します。

まとめ

この記事では、コンパイラの基本概念から出発し、Solidityコンパイラの脆弱性を紹介し、実際のEthereum開発環境で引き起こされる可能性のあるセキュリティリスクを分析し、最後に開発者やセキュリティ担当者にいくつかの実際的なセキュリティ提案を提供します。

! 【Solidityコンパイラの脆弱性解析と対策】###https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(

ETH2.56%
原文表示
このページには第三者のコンテンツが含まれている場合があり、情報提供のみを目的としております(表明・保証をするものではありません)。Gateによる見解の支持や、金融・専門的な助言とみなされるべきものではありません。詳細については免責事項をご覧ください。
  • 報酬
  • 5
  • 共有
コメント
0/400
staking_grampsvip
· 15時間前
バグが多すぎて、誰が開発する勇気があるのか
原文表示返信0
JustHereForMemesvip
· 07-23 05:15
コンパイラにも大きな問題がありますね、逃げます逃げます。
原文表示返信0
BakedCatFanboyvip
· 07-22 21:56
バグはすべて拾うということですか?
原文表示返信0
OldLeekNewSicklevip
· 07-22 21:56
高級初心者はバグを見て、底辺初心者は注文板を見つめる
原文表示返信0
RektCoastervip
· 07-22 21:52
コンパイラもバグが出るの? 本当に私を驚かせてくれる。
原文表示返信0
いつでもどこでも暗号資産取引
qrCode
スキャンしてGateアプリをダウンロード
コミュニティ
日本語
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)