3 Şubat sabahı (+8 saat dilimi), sistemimiz HypeBears NFT sözleşmesine yönelik bir saldırı işlemi tespit etti: 0xfa97c3476aa8aeac662dae0cc3f0d3da48472ff4e7c55d0e305901ec37a2f704. Yaptığımız araştırma sonucunda bunun ERC721'in _safeMint fonksiyonundan kaynaklanan bir yeniden giriş (re-entrancy) saldırısı olduğu anlaşıldı.
Temel Neden
Proje, bir hesabın basabileceği NFT sayısına bir sınırlama getirmiştir. Temel olarak, bir hesabın NFT basıp basmadığını kaydeden addressMinted adlı bir eşleme (map) bulunmaktadır.
NFT basılırken, kod OZ referans uygulamasının _safeMint fonksiyonunu kullanmaktadır. Bu fonksiyon güvenli (safe) olarak nitelendirilir; çünkü alıcının ERC721 token'larını alıp alamayacağını kontrol eder. Bu, bir NFT'nin ERC721 token'larını işleyemeyen bir sözleşmeye basılması durumunu önleyebilir. Belgeye göre:
Eğer
tobir akıllı sözleşmeye atıfta bulunuyorsa, güvenli bir transfer sırasında çağrılan IERC721Receiver.onERC721Received fonksiyonunu uygulaması gerekir. Aşağıdaki kod,_safeMintfonksiyonunun OZ uygulamasını göstermektedir.

Ancak bu harici fonksiyon çağrısı bir güvenlik açığı oluşturmaktadır. Özellikle, saldırgan onERC721Received geri çağrımı (callback) içinde yeniden giriş çağrısı gerçekleştirebilir. Örneğin, güvenlik açığı bulunan HypeBears sözleşmesinde, saldırgan onERC721Received geri çağrımı içinde mintNFT fonksiyonunu tekrar çağırabilir (çünkü addressMinted henüz güncellenmemiştir).

Saldırı
Aşağıdaki ekran görüntüsü saldırı işlemini göstermektedir.

Dersler
SafeMint tarafından oluşturulan risk, güvenlik araştırmacıları tarafından daha önce ele alınmıştır: bağlantı1 bağlantı2. Bununla birlikte, savunmasız kodları ve gerçek dünyadaki saldırıları görmeye devam ediyoruz. QBridge güvenlik olayındaki safeTransfer örneğinde gösterildiği gibi, güvenli bir fonksiyon kullanmak güvenli bir sözleşmeyi garanti etmez 😃.



