Giriş
Ethereum'daki NFT ekosisteminin gelişmesi ve buna bağlı güvenlik sorunlarının artmasıyla birlikte, bu güvenlik sorunlarını tanıtmak ve geliştiricilere akıllı sözleşmeleri güvence altına almaları için öneriler sunmak amacıyla bir dizi blog yazısı yayınlayacağız. Bu blog yazısında, NFT sözleşmelerindeki yeniden giriş (reentrancy) sorununu ve ilgili güvenlik açığını nasıl azaltabileceğimizi ele alacağız.
Yeniden Giriş (Reentrancy) Nedir?
Wikipedia'ya göre
Bilişimde, birden fazla çağrının birden fazla işlemci üzerinde eş zamanlı olarak ya da tek işlemcili bir sistemde güvenle çalışabildiği; yeniden girilebilir bir prosedürün yürütülmesinin ortasında kesintiye uğrayıp önceki çağrıları tamamlanmadan önce güvenle tekrar çağrılabildiği ("yeniden girildiği") durumlarda, bir bilgisayar programı veya alt programa yeniden girilebilir (reentrant) denir.
Akıllı bir sözleşmede yeniden giriş, bir fonksiyonun başka bir sözleşmenin harici çağrısını gerçekleştirmesi ve bu çağrının orijinal çağrı tamamlanmadan önce orijinal fonksiyonu (veya diğer fonksiyonları) tekrar çağırması durumunda ortaya çıkabilir. Harici çağrı güvenilmeyen bir varlık tarafından kontrol ediliyorsa (örneğin, kötü niyetli bir sözleşme), bu beklenmedik sonuçlara yol açabilir. Bunun nedeni, bazı fonksiyonlarda sonucun sözleşme durumuna bağlı olmasıdır. Sözleşme durumu harici çağrıdan sonra güncellenecektir. Ancak fonksiyonun yeniden giriş çağrısı, güncellenmiş durum yerine eski durumu kullanacaktır.
Yeniden giriş, akıllı sözleşmelerde yaygın bir sorun olmaya devam etmektedir; örneğin MakerDAO saldırısı, Uniswap üzerindeki ERC777 ve diğerleri (BlockSec Academy üzerinde Reentrancy aratın).
NFT'de Yeniden Giriş

NFT sözleşmeleri için, geliştiriciler tarafından göz ardı edilebilecek bazı örtük harici fonksiyon çağrıları mevcuttur. Bunlar arasında onERC721Received ve onERC1155Received fonksiyonları yer almaktadır. onERC721Received fonksiyonu, alıcı sözleşmenin NFT'leri işleyip işleyemeyeceğini kontrol etmek için tasarlanmıştır (NFT'lerin sonsuza kadar kilitlenmesini önlemek amacıyla). Bu fonksiyon, ERC721 sözleşmesinin safeTransferFrom ve _safeMint işlevlerinde çağrılmaktadır. Benzer bir durum ERC1155 sözleşmesinde de mevcuttur. Bu harici fonksiyon çağrıları nedeniyle, sözleşme geliştiricileri tarafından fark edilmeden yeniden giriş gerçekleşebilir.
Tek Fonksiyonlu Yeniden Giriş
Tek fonksiyonlu yeniden giriş, yeniden giriş saldırısının daha basit bir biçimidir. Bu tür yeniden giriş saldırısında, yeniden çağrılan fonksiyon orijinal fonksiyonla aynıdır. Bir saldırgan, fonksiyonun ilk çağrısı tamamlanmadan önce fonksiyonu tekrar tekrar çağırabilir. NFT sözleşmelerinde bu durum genellikle mint işlemiyle ilgili fonksiyonlarda gerçekleşir.
Örneğin, bazı NFT projeleri her kullanıcıya ücretsiz NFT basma hakkı tanıyabilir, tüm proje için maksimum arz belirleyebilir ya da bir kullanıcının sahip olabileceği maksimum NFT miktarını sınırlayabilir. Genellikle bu kısıtlamalar, gerçek mint işleminden önce kontrol edilir. Ancak bu kısıtlamalarla ilgili durumlar safeMint fonksiyonundan sonra güncellenirse, saldırgan mint fonksiyonuna yeniden girerek kısıtlamaları aşabilir; çünkü ilgili durumlar bu fonksiyonun ilk çağrısıyla aynı olmaya devam eder. Önceki blog yazımızda paylaşılan HypeBears yeniden giriş saldırısı buna bir örnektir.
Daha karmaşık bir tek fonksiyonlu yeniden giriş, safeMint fonksiyonunun bir döngü içinde kullanılması ve kısıtlamaların döngü başlamadan önce kontrol edilmesi durumunda ortaya çıkar. Bu senaryoda, bazı durumlar harici çağrıdan önce otomatik olarak güncellenmiş olsa bile, döngüdeki kalan safeMint fonksiyon çağrıları doğrulamayı atlayabilir; çünkü döngü zaten başlamış ve doğrulama döngü başlamadan önce gerçekleşmiştir.
Örneğin, başka bir yazıda gösterilen örnekte, mintNFT fonksiyonu kullanıcının basmak istediği NFT sayısının mevcut arzla birlikte maksimum arzı aşıp aşmadığını kontrol edecektir. safeMint fonksiyonu, onERC721Received harici çağrısından önce toplam arzı günceller. Ancak saldırgan bunu istismar edebilir; çünkü safeMint fonksiyonu her seferinde toplam arzı yalnızca 1 artırır. Dolayısıyla saldırgan, döngüdeki safeMint'in ilk fonksiyon çağrısında mintNFT fonksiyonuna yeniden girerse, toplam arz eski arz artı mintNFT'nin ilk çağrısıyla basılacak NFT miktarı yerine eski arz artı 1 olur.
Çapraz Fonksiyonlu Yeniden Giriş
Saldırgan, aynı fonksiyona girmek yerine, orijinal fonksiyonla ortak durumları paylaşan veya bu duruma bağlı olan başka bir fonksiyona girebilir. Önceki blog yazılarımızda Revest vakası ve OMNI vakası için bazı örnekleri ayrıntılı olarak ele aldık.
Özet ve Öneriler
NFT akıllı sözleşme geliştiricileri için yeniden giriş tehdidini azaltmaya yönelik bazı öneriler aşağıda yer almaktadır.
- Kodunuzda Kontroller-Etkiler-Etkileşimler Desenini kullanın.
- Harici çağrılar içerecek üçüncü taraf kütüphaneler kullanırken dikkatli olun. NFT sözleşmeleri için
onERC721ReceivedveonERC1155Receivedfonksiyonunun örtük geri çağırmasına (callback) karşı temkinli olun.
Bu Serideki Diğer Makaleyi Okuyun
BlockSec Hakkında
BlockSec, 2021 yılında dünya genelinde tanınmış güvenlik uzmanlarından oluşan bir grup tarafından kurulmuş öncü bir blok zinciri güvenlik şirketidir. Şirket, kitlesel benimsenmesini kolaylaştırmak amacıyla gelişmekte olan Web3 dünyasının güvenliğini ve kullanılabilirliğini artırmaya kararlıdır. Bu doğrultuda BlockSec; akıllı sözleşme ve EVM zinciri güvenlik denetimi hizmetleri, güvenlik geliştirme ve tehditleri proaktif olarak engelleme amacıyla Phalcon platformu, fon takibi ve araştırma için MetaSleuth platformu ve kripto dünyasında Web3 geliştiricilerinin verimli şekilde gezinmesi için MetaSuites eklentisini sunmaktadır.
Bugüne kadar şirket, MetaMask, Uniswap Foundation, Compound, Forta ve PancakeSwap gibi 300'den fazla saygın müşteriye hizmet vermiş; Matrix Partners, Vitalbridge Capital ve Fenbushi Capital gibi önde gelen yatırımcılardan iki finansman turunda on milyonlarca ABD doları yatırım almıştır.
Resmi web sitesi: https://blocksec.com/
Resmi Twitter hesabı: https://twitter.com/BlockSecTeam



