Reentrancy saldırıları, akıllı sözleşme güvenliğindeki en kötü şöhrete sahip zayıflıklardan birini temsil eder ve çeşitli blockchain protokolleri üzerinden milyonlarca dolarlık çalınan fonlardan sorumludur. Bu makale, reentrancy zayıflıklarının arkasındaki mekanizmaları incelemekte ve güvenlik bilincine sahip geliştiricilerin uygulaması gereken kapsamlı önleme tekniklerini sunmaktadır.
Reentrancy Saldırısı Nedir?
Temelinde, bir yeniden giriş saldırısı, bir akıllı sözleşmedeki bir fonksiyonun, önceki yürütmesi tamamlanmadan tekrar tekrar çağrılması durumunda meydana gelir. Temel zayıflık, bir akıllı sözleşmenin kendi durum değişikliklerini çözmeden önce bir dış sözleşmeyi çağırdığında ortaya çıkar ve bu durum istismar fırsatı yaratır.
Tipik bir senaryoda, Sözleşme A, Sözleşme B ile bir fonksiyonunu çağırarak etkileşime geçer. Kritik güvenlik açığı, Sözleşme B'nin Sözleşme A'nın hala orijinal fonksiyonunu yürütürken geri çağırma yeteneği kazanmasıyla ortaya çıkar. Bu özyinelemeli etkileşim modeli, potansiyel bir istismar için bir temel oluşturur.
Yeniden Giriş Saldırıları Nasıl Çalışır: Adım Adım Analiz
Bu senaryoyu düşünün: Sözleşme A toplamda 10 ETH tutuyor, Sözleşme B Sözleşme A'ya 1 ETH yatırmış durumda. Zafiyet, Sözleşme B'nin aşağıdaki sırayla fonlarını çekmeye çalıştığında kullanılabilir hale geliyor:
Sözleşme B, Sözleşme A'daki withdraw() fonksiyonunu çağırır.
Sözleşme A, Sözleşme B'nin bakiyesinin 0'dan büyük olduğunu doğrular (kontrolü geçer)
Contract A, ETH'yi Contract B'ye gönderir, bu da Contract B'nin geri dönüş fonksiyonunu tetikler.
Contract A, Contract B'nin bakiyesini sıfıra güncelleyebilmesi için, Contract B'deki fallback fonksiyonu withdraw()'i tekrar çağırır.
Sözleşme A, Sözleşme B'nin bakiyesini kontrol eder, bu hala 1 ETH ( henüz güncellenmedi) gösteriyor.
Süreç, Sözleşme A'nın fonları tükenene kadar tekrar eder.
Ana zafiyet, bakiyenin güncellenmesinin ETH transferinden sonra gerçekleşmesidir, bu da saldırganın bakiye sıfıra ayarlanmadan önce aynı bakiyeyi birden fazla kez istismar etmesine olanak tanır.
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdrawAll() public {
uint bal = balances[msg.sender];
require(bal > 0);
// Güvenlik Açığı: Durum güncellemesinden önce dış çağrı
(bool gönderildi, ) = msg.sender.call{value: bal}("");
require(gönderildi, "Ether gönderme başarısız");
// Durum güncellemesi çok geç gerçekleşiyor
balances[msg.sender] = 0;
}
}
Şimdi, bir saldırganın bu güvenlik açığından nasıl yararlanabileceğine bakalım:
katılık
// Yeniden giriş zafiyetini istismar eden saldırı sözleşmesi
sözleşme Attack {
EtherStore kamu etherStore;
constructor(adres _etherStoreAddress) {
etherStore = EtherStore(_etherStoreAddress);
}
// EtherStore'un Ether gönderdiğinde çağrılan yedek fonksiyon
receive() harici ödenecek {
if(adres(etherStore).denge >= 1 ether) {
// withdrawAll fonksiyonunu yeniden girin
etherStore.withdrawAll();
}
}
function attack() external payable {
require(msg.value >= 1 ether);
// EtherStore'da bir bakiye oluşturmak için para yatırın
etherStore.deposit{değer: 1 ether}();
// Çekim sürecini başlat, yeniden giriş saldırısını tetikle
etherStore.withdrawAll();
}
}
Saldırı dizisi, saldırganın attack() çağrısıyla başlar. Bu, bir bakiye oluşturmak için 1 ETH yatırır ve ardından withdrawAll()'i çağırır. EtherStore ETH'yi geri gönderdiğinde, Attack sözleşmesindeki receive() fonksiyonunu tetikler, bu da bakiye güncellenmeden önce withdrawAll()'i tekrar çağırır. Bu döngü, EtherStore'un fonları tükenene kadar devam eder.
Kapsamlı Önleme Teknikleri
Güvenlik bilincine sahip geliştiriciler, yeniden giriş (reentrancy) açıklarına karşı korunmak için üç sağlam teknik uygulayabilirler:
Kontroller-Etkiler-Etkileşimler desenini takip ederek, sözleşme dış etkileşimlerden önce durumunu günceller, böylece bir saldırgan yeniden girmeye çalışsa bile, güncellenmiş durumla karşılaşacaktır (sıfır bakiye).
3. Proje Düzeyi Koruma: Küresel Yeniden Giriş Koruyucusu
Birden fazla etkileşimli sözleşmeye sahip karmaşık projeler için, küresel bir yeniden giriş koruyucusu uygulamak sistem genelinde koruma sağlar:
katılık
sözleşme GlobalReentrancyGuard {
bool özel _notEntered = true;
// Projedeki tüm sözleşmeler GlobalReentrancyGuard'dan miras alır
sözleşme SecureContract GlobalReentrancyGuard'dır {
fonksiyon vulnerableOperation() public globalNonReentrant {
// Proje genelinde reentrancy'den korunmuştur
}
}
Bu yaklaşım, birbirleriyle etkileşime giren birden fazla sözleşmenin bulunduğu DeFi protokollerinde, çapraz sözleşme yeniden giriş saldırılarına karşı koruma sağlamak açısından özellikle değerlidir.
Yeniden Giriş Açıklarının Gerçek Dünya Üzerindeki Etkisi
Yeniden giriş zafiyetleri, blockchain tarihinin en yıkıcı istismarlarına yol açmıştır. 2016'daki ünlü DAO saldırısı, o dönemde yaklaşık ( milyon değerinde 3.6 milyon ETH'nin çalınmasına neden oldu ve nihayetinde Ethereum Classic'i yaratan Ethereum hard fork'una yol açtı.
Daha yakın bir tarihte, 2020'de, Lendf.Me protokolü yaklaşık $50 milyon kaybettiği bir yeniden giriş saldırısıyla, artan farkındalığa rağmen bu zayıflıkların akıllı sözleşme güvenliğine önemli riskler oluşturmaya devam ettiğini vurgulamaktadır.
Güvenlik En İyi Uygulamaları
Belirtilen özel tekniklerin ötesinde, geliştiricilerin bu ek güvenlik uygulamalarını takip etmesi gerekir:
Her zaman en son Solidity sürümünü kullanın bu, geliştirilmiş güvenlik özellikleri sunar
Konu sözleşmeleri saygın firmalar tarafından kapsamlı güvenlik denetimlerine tabi tutulur
Kapsamlı test kapsamı uygulayın kenar durumları için birim testleri dahil
Yeni sözleşmeleri üretime dağıtırken minimum ETH maruziyeti ile başlayın
Yüksek değerli sözleşmeler için resmi doğrulamayı düşünün
Bu savunma tekniklerini uygulayarak ve güvenlik en iyi uygulamalarını takip ederek, geliştiriciler reentrancy saldırısı riskini önemli ölçüde azaltabilir ve blockchain uygulamaları için daha güvenli akıllı sözleşmeler oluşturabilir.
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
Akıllı Sözleşmelerde Yeniden Giriş Saldırıları: Açığı Anlamak ve Önleme Stratejileri Uygulamak
Reentrancy saldırıları, akıllı sözleşme güvenliğindeki en kötü şöhrete sahip zayıflıklardan birini temsil eder ve çeşitli blockchain protokolleri üzerinden milyonlarca dolarlık çalınan fonlardan sorumludur. Bu makale, reentrancy zayıflıklarının arkasındaki mekanizmaları incelemekte ve güvenlik bilincine sahip geliştiricilerin uygulaması gereken kapsamlı önleme tekniklerini sunmaktadır.
Reentrancy Saldırısı Nedir?
Temelinde, bir yeniden giriş saldırısı, bir akıllı sözleşmedeki bir fonksiyonun, önceki yürütmesi tamamlanmadan tekrar tekrar çağrılması durumunda meydana gelir. Temel zayıflık, bir akıllı sözleşmenin kendi durum değişikliklerini çözmeden önce bir dış sözleşmeyi çağırdığında ortaya çıkar ve bu durum istismar fırsatı yaratır.
Tipik bir senaryoda, Sözleşme A, Sözleşme B ile bir fonksiyonunu çağırarak etkileşime geçer. Kritik güvenlik açığı, Sözleşme B'nin Sözleşme A'nın hala orijinal fonksiyonunu yürütürken geri çağırma yeteneği kazanmasıyla ortaya çıkar. Bu özyinelemeli etkileşim modeli, potansiyel bir istismar için bir temel oluşturur.
Yeniden Giriş Saldırıları Nasıl Çalışır: Adım Adım Analiz
Bu senaryoyu düşünün: Sözleşme A toplamda 10 ETH tutuyor, Sözleşme B Sözleşme A'ya 1 ETH yatırmış durumda. Zafiyet, Sözleşme B'nin aşağıdaki sırayla fonlarını çekmeye çalıştığında kullanılabilir hale geliyor:
Ana zafiyet, bakiyenin güncellenmesinin ETH transferinden sonra gerçekleşmesidir, bu da saldırganın bakiye sıfıra ayarlanmadan önce aynı bakiyeyi birden fazla kez istismar etmesine olanak tanır.
Saldırının Anatomisi: Teknik Uygulama
Hassas kod desenini inceleyelim:
katılık // Hassas EtherStore sözleşmesi contract EtherStore { mapping(address => uint) public balances;
}
Şimdi, bir saldırganın bu güvenlik açığından nasıl yararlanabileceğine bakalım:
katılık // Yeniden giriş zafiyetini istismar eden saldırı sözleşmesi sözleşme Attack { EtherStore kamu etherStore;
}
Saldırı dizisi, saldırganın attack() çağrısıyla başlar. Bu, bir bakiye oluşturmak için 1 ETH yatırır ve ardından withdrawAll()'i çağırır. EtherStore ETH'yi geri gönderdiğinde, Attack sözleşmesindeki receive() fonksiyonunu tetikler, bu da bakiye güncellenmeden önce withdrawAll()'i tekrar çağırır. Bu döngü, EtherStore'un fonları tükenene kadar devam eder.
Kapsamlı Önleme Teknikleri
Güvenlik bilincine sahip geliştiriciler, yeniden giriş (reentrancy) açıklarına karşı korunmak için üç sağlam teknik uygulayabilirler:
1. Fonksiyon Seviyesi Koruma: nonReentrant Modifikatörü
Bireysel işlev düzeyinde en yaygın koruma, bir reentrancy guard uygulamaktır:
katılık sözleşme ReentrancyGuard { bool özel kilitli = false;
}
Bu yaklaşım, işlev yürütülürken sözleşmeyi kilitler, işlev tamamlanıp durumu açana kadar herhangi bir rekürsif çağrıyı önler.
2. Çapraz Fonksiyon Koruması: Kontroller-Etkiler-Etkileşimler Deseni
Bu temel güvenlik modeli, birden fazla işlevdeki zayıflıkları ortadan kaldırmak için kodu yeniden yapılandırır:
katılık // HASSAS UYGULAMA function withdrawAll() public { uint bal = balances[msg.sender]; require(bal > 0);
}
// GÜVENLİ UYGULAMA function withdrawAll() public { uint bal = balances[msg.sender]; require(bal > 0); // Kontroller
}
Kontroller-Etkiler-Etkileşimler desenini takip ederek, sözleşme dış etkileşimlerden önce durumunu günceller, böylece bir saldırgan yeniden girmeye çalışsa bile, güncellenmiş durumla karşılaşacaktır (sıfır bakiye).
3. Proje Düzeyi Koruma: Küresel Yeniden Giriş Koruyucusu
Birden fazla etkileşimli sözleşmeye sahip karmaşık projeler için, küresel bir yeniden giriş koruyucusu uygulamak sistem genelinde koruma sağlar:
katılık sözleşme GlobalReentrancyGuard { bool özel _notEntered = true;
}
// Projedeki tüm sözleşmeler GlobalReentrancyGuard'dan miras alır sözleşme SecureContract GlobalReentrancyGuard'dır { fonksiyon vulnerableOperation() public globalNonReentrant { // Proje genelinde reentrancy'den korunmuştur } }
Bu yaklaşım, birbirleriyle etkileşime giren birden fazla sözleşmenin bulunduğu DeFi protokollerinde, çapraz sözleşme yeniden giriş saldırılarına karşı koruma sağlamak açısından özellikle değerlidir.
Yeniden Giriş Açıklarının Gerçek Dünya Üzerindeki Etkisi
Yeniden giriş zafiyetleri, blockchain tarihinin en yıkıcı istismarlarına yol açmıştır. 2016'daki ünlü DAO saldırısı, o dönemde yaklaşık ( milyon değerinde 3.6 milyon ETH'nin çalınmasına neden oldu ve nihayetinde Ethereum Classic'i yaratan Ethereum hard fork'una yol açtı.
Daha yakın bir tarihte, 2020'de, Lendf.Me protokolü yaklaşık $50 milyon kaybettiği bir yeniden giriş saldırısıyla, artan farkındalığa rağmen bu zayıflıkların akıllı sözleşme güvenliğine önemli riskler oluşturmaya devam ettiğini vurgulamaktadır.
Güvenlik En İyi Uygulamaları
Belirtilen özel tekniklerin ötesinde, geliştiricilerin bu ek güvenlik uygulamalarını takip etmesi gerekir:
Bu savunma tekniklerini uygulayarak ve güvenlik en iyi uygulamalarını takip ederek, geliştiriciler reentrancy saldırısı riskini önemli ölçüde azaltabilir ve blockchain uygulamaları için daha güvenli akıllı sözleşmeler oluşturabilir.