著者:Jagjit Singh, CoinTelegraph; Compiled by Five Baht, Golden Finance
I. スマートコントラクトにおける潜在的な脆弱性
その画期的な性質にもかかわらず、スマートコントラクトは悪意のある当事者によって悪用される可能性のある欠陥と無縁ではありません。
不適切な入力検証は一般的な弱点であり、攻撃者が予期しない入力を提供することで契約の実行に影響を与えることを可能にします。 さらに、ビジネスロジックの不適切な適用は、脆弱性につながる予期せぬ動作やロジックギャップをコントラクト内に生み出す可能性があります。 さらに、安全でない外部呼び出し(例えば、外部データソースや他のコントラクトへのインターフェースを含む呼び出し)は、適切に処理されないと脆弱性を引き起こす可能性があります。
リエントリー攻撃とは、コントラクトが自身の状態変更を完了する前に、外部から別のコントラクトを呼び出すことで発生する脆弱性です。 これにより、呼び出されたコントラクトは、呼び出されたコントラクトに再入力し、潜在的にそのオペレーションの一部を再び実行することができます。 これは予期せぬ動作につながり、攻撃者がコントラクトの状態を変更することを可能にします。
このような攻撃の可能性を考慮すると、開発者は外部コントラクトやデータソースを使用する際にも注意を払い、予期せぬ動作や脆弱性を避けるために、外部呼び出しが正しく処理されるようにする必要があります。 スマートコントラクトのテストなどのセキュリティ手順に細心の注意を払うことで、進化する脅威からスマートコントラクトを守ることができます。
II.スマートコントラクトにおける再侵入攻撃とは何ですか?
スマートコントラクトにおいて、リエントリー攻撃は、コントラクトが自身の状態変更を完了する前に、外部から別のコントラクトや関数を呼び出すことで発生します。
これにより、呼び出されたコントラクトは呼び出し元のコントラクトに再入力し、潜在的にそのオペレーションの一部を再び実行することができるため、予期せぬ悪意のある振る舞いが頻発する可能性があります。 例えば、コントラクトAはコントラクトBを呼び出して資金を送金し、その後自身の状態を変更します。
コントラクトBのコードには、コントラクトAが状態の変更を完了する前に、コントラクトAに再入力し、送金関数を再実行できる可能性のあるコールバック関数が含まれている可能性があります。 これにより、攻撃者は最初のトランザクションを完了する前に、契約から何度も資金にアクセスできるようになります。
イーサリアム・ブロックチェーン上の分散型自律組織(DAO)の悪名高い2016年のハッキングも有名な例です。 攻撃者はスマートコントラクトのコードにあるリエントリーの欠陥を悪用してDAOから資金を再帰的に抜き取り、最終的に数百万ドル相当のイーサ(ETH)の盗難につながりました。

また、このような悪質な攻撃も行われています。
さらに、Uniswap、Lendf.Me、BurgerSwap、SURGEBNB、Cream Finance、Siren Protocolなど、複数の分散型金融(DeFi)プロトコルが、リエントラントの脆弱性によって多額の金銭的損失を被りました。 これらの侵害は、350万ドルから2500万ドルの損失をもたらし、DeFi空間におけるリエントラント脆弱性の継続的な脅威を浮き彫りにしています。
3:リエントリー攻撃の仕組み
リエントリー攻撃は、スマートコントラクトの関数と外部呼び出しの逐次実行を活用してループを形成し、攻撃者が特定の関数を完了する前に複数回実行することを可能にします。
攻撃者のコントラクトは、被害者のコントラクトを効果的に「スプーフ」して、被害者が状態変更を完了する前に攻撃者のコントラクトをコールバックします。 その結果、引き出しが繰り返されたり、その他の怠慢な行動が取られたりする可能性があります。

上の図は、スマートコントラクトに対するリエントリー攻撃を示しています。 攻撃者の契約は被害者の「withdraw()」関数を呼び出し、残高を更新する前にイーサを送信します。 その後、攻撃者のフォールバック関数が起動し、被害者のコントラクトから資金を流出させるために再度withdraw()を再帰的に呼び出す。 この攻撃は、被害者が資金を送る前に残高を更新しなかったことを利用します。
単純化した例を使って、再突入攻撃がどのように機能するのかを分解してみましょう:
「引き出し」機能を持つスマートコントラクト
ユーザーが資金を引き出すことができるデジタルウォレットのスマートコントラクトがあるとします。 ユーザーの残高を追跡することに加えて、契約は資金の引き出しを容易にするための引き出し機能も持っています。 引き出し機能は通常、ユーザーがスマートコントラクトから個人のウォレットにトークンやイーサを引き出すことを可能にします。
ユーザーとのやり取りと機能の実行
ユーザーは自分でウォレットからの引き出しを要求します。 ユーザーは引き出し機能を使い、希望する引き出し額を入力します。
引き出し関数は、呼び出されたときにユーザーが引き出しを行うのに十分な資金を持っているかどうかを確認します。 要求が満たされた場合、必要な資金をユーザーが選択したアドレスに送金します。
外部呼び出し
ここで弱点が現れます。 引き出しがユーザーの残高に反映される前に、契約は別の契約や口座に外部コールを行う。
再帰呼び出し
外部コントラクトのコードに、元のコントラクトを再度呼び出せる関数(別の引き出し関数など)が含まれている場合、再帰ループが作成されます。 これにより、完了する前にwithdrawメソッドが再度呼び出されるようになります。
攻撃者は次に、悪意のあるコントラクトを使ってこのループを悪用します。 攻撃者のコントラクトは、ウォレットのコントラクトが外部コントラクトを呼び出している間に、残高が更新される前に、ウォレットの引き出し関数をすばやく再度呼び出します。
リエントリー機能
場合によっては、スマートコントラクトのリエントリー機能(コントラクトがデータもイーサもないコールを受け取ったときに作動する独自の機能)が攻撃者に利用されることがあります。 リエントリー攻撃は、資金がまだ処理されている間にフォールバック関数を繰り返し呼び出すことで実行できます。
操作と繰り返される引き出し
攻撃者のコントラクトは、ウォレットのコントラクトが外部からのコールを受信するまで残高の更新を遅らせるため、同じトランザクションで引き出し関数を再利用できます。 そのため、資金が認証されずに引き出されやすくなり、攻撃者は法的権利以上の資金を盗むことができます。 その結果、ウォレット契約のユーザーに大きな金銭的損失をもたらします。
IV.再突入攻撃の結果
再突入攻撃は、大きな金銭的損失を引き起こす可能性があるため、スマートコントラクトのユーザーに深刻な影響を与える可能性があります。
再突入攻撃の最も直接的な結果の1つは、脆弱なスマートコントラクトに保有されている現金の不正な引き出しや操作です。 攻撃者はこの脆弱性を利用して、コントラクトから繰り返し資金を引き出し、コントラクトの残高を枯渇させ、影響を受けたコントラクトに資産を投資または保管していたユーザーに大きな金銭的損失を与える可能性があります。
さらに、再エントリー攻撃は、スマートコントラクトとブロックチェーン技術の安全性と完全性に対するユーザーの信頼を損なう可能性があります。 再侵入の脆弱性は、2016年のイーサブロックチェーンでのDAOハッキングのような有名なインシデントが証明しているように、多大な金銭的損失をもたらし、コミュニティの評判を傷つけたように、壊滅的な影響をもたらす可能性があります。
短期的な金銭的影響のほかに、再侵入攻撃は規制や法的な懸念、投資家の信頼の低下、ブロックチェーンプラットフォームやプロジェクトの評判へのダメージなど、長期的な影響を及ぼす可能性があります。 攻撃に対する脆弱性が認識されることで、ユーザーはスマートコントラクトとのやり取りや分散型アプリケーション(DApps)への投資に慎重になり、ブロックチェーン技術の採用と拡大が妨げられる可能性があります。
V. 再侵入攻撃を緩和する方法
再侵入の脅威を緩和するためには、スマートコントラクトの作成と監査におけるベストプラクティスを実施することが必要です。
これには、セキュリティの実績がある評判の良いコードライブラリの使用が含まれ、これがこの目標を達成する1つの方法です。 これらのライブラリは広範囲にテストされ、査読を受けているため、脆弱性を導入する可能性が低くなります。
開発者はまた、「チェック効果-相互作用」設計のようなセキュリティチェックを使用し、状態変化がアトミックに起こるようにすることで、再突入攻撃の可能性を最小限にする必要があります。 もし利用可能であれば、リエントラントセキュアなスマートコントラクト開発フレームワークを使用することで、そのような脆弱性に対する防御を追加することができます。
これらのフレームワークには通常、リエントラント攻撃を回避するために特別に設計された組み込みメソッドや保護機能が含まれているため、開発者が手作業でセキュリティ保護を追加することはまず不可能です。 しかし、ブロックチェーンのセキュリティはまだ進化しているため、開発者は新しい脅威や脆弱性を探し続けなければなりません。