2月3日午前(+8時差)、当社のシステムは、HypeBears NFTコントラクトに対する攻撃トランザクション 0xfa97c3476aa8aeac662dae0cc3f0d3da48472ff4e7c55d0e305901ec37a2f704 を報告しました。調査の結果、ERC721の_safeMint関数によって引き起こされたリエントランシー攻撃であることが判明しました。
原因
このプロジェクトでは、アカウントがミントできるNFTに制限があります。基本的に、アカウントがNFTをミントしたかどうかを記録するaddressMintedというマップがあります。
NFTをミントする際、コードはOZリファレンス実装の_safeMint関数を使用しています。この関数は、受信者がERC721トークンを受け取れるかどうかをチェックするため「安全」です。これにより、ERC721トークンを処理できないコントラクトにNFTがミントされるケースを防ぐことができます。 ドキュメントによると:
to がスマートコントラクトを参照する場合、IERC721Receiver.onERC721Received を実装する必要があり、これはセーフ転送時に呼び出されます。以下のコードは、
_safeMint関数のOZ実装を示しています。

しかし、この外部関数呼び出しはセキュリティ上の抜け穴を生み出します。具体的には、攻撃者はonERC721Receivedコールバック内で再入可能呼び出しを実行できます。例えば、脆弱なHypeBearsコントラクトでは、攻撃者はonERC721ReceivedコールバックでmintNFT関数を再度呼び出すことができます(addressMintedがまだ更新されていないため)。

攻撃
以下のスクリーンショットは、攻撃トランザクションを示しています。

学び
SafeMintによるリスクは、セキュリティ研究者によって議論されてきました。link1 link2。しかし、脆弱なコードと実際の攻撃を依然として目にします。QBridgeセキュリティインシデントのsafeTransferで示されているように、「安全な」関数を使用しても「安全な」コントラクトが保証されるわけではありません😃。



