Sayısız saatimi sözleşme açıklarını hata ayıklamakla geçirdim ve size söyleyeyim - yeniden giriş saldırıları akıllı sözleşmelerin sessiz katilleri. Aldatıcı bir şekilde basit ama yıkıcı derecede etkili. Gelin bunların ne olduğunu ve fonlarınızı tüketmeden önce nasıl durdurabileceğimizi inceleyelim.
İlk kez bir reentrancy zayıflığıyla karşılaştığımda, birinin bu kadar masum görünen bir kod parçasını nasıl istismar edebileceğini anlamaya çalışarak saatlerce uyku kaybettim. Kavram sinir bozucu bir şekilde basit: bir sözleşme, ilk yürütme tamamlanmadan önce başka birine geri çağrı yapabilir.
Bunu hayal edin: ContractA'nın 10 ETH'si var ve ContractB buna 1 ETH yatırdı. ContractB fonlarını çektiğinde, ContractA, B'nin bakiyesini sıfıra güncellemeden önce ETH'yi gönderir. Bu küçük sıralama hatası büyük bir güvenlik açığı yaratır.
Ne oluyor? Kötü niyetli sözleşmenin geri çağırma fonksiyonu hemen withdraw()'i tekrar çağırıyor ve bakiye henüz güncellenmediği için bakiye kontrolünden tekrar geçiyor! Bu döngü, ContractA tamamen boşalana kadar tekrarlanır. Kötü değil mi?
İşte bir saldırganın bunu kodda nasıl istismar ettiğine dair:
// Saldırı sözleşmesi çağrıları withdraw()
// ContractA ETH gönderir bu fallback() tetikler.
// fallback(), bakiye güncellenmeden önce withdraw()'i tekrar çağırır.
// Durumlar çalınana kadar durulayıp tekrarlayın
Milyonlarca kaybeden projelere tanık oldum çünkü bu basit saldırı vektörünü anlamadılar. Hala bu acemi hatasını yapan birçok geliştiricinin olması beni öfkelendiriyor.
Sözleşmelerinizi Korumanın Üç Tekniği
nonReentrant Modifikatörü
Bu, yürütme sırasında sözleşmeyi kilitler ve bu düzenleyiciyle işaretlenmiş herhangi bir işlevin yeniden girilmesini engeller. Basit ama etkili.
// GÜVENLİ
require(balance > 0);
bakiye = 0; // Durumu dış etkileşimlerden ÖNCE güncelle
send(ether);
Her zaman ETH veya token göndermeden önce durumunuzu güncelleyin!
GlobalReentrancyGuard
Birden fazla etkileşimli sözleşmeye sahip projeler için, bu, paylaşılan bir kilitleme mekanizması kullanarak tüm sözleşme ekosisteminizde koruma sağlar.
Bu teknikler sadece akademik değil - sayısız projeyi tamamen mali iflastan kurtardı.
Çok sayıda geliştirici hâlâ "bana olmaz" diye düşünüyor ve bu korumaları atlıyor. O kişi olma. ETH veya token gönderen her bir fonksiyon, bu koruma mekanizmalarından en az birini uygulamalıdır.
Unutmayın, akıllı sözleşme geliştirmede paranoya bir özellik, hata değildir. Kaçırılan bir koruma her şeyi kaybettirebilir.
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.
Reentrancy Saldırısı: Bu Akıllı Sözleşme Zafiyetini Anlamak ve Önlemek
Sayısız saatimi sözleşme açıklarını hata ayıklamakla geçirdim ve size söyleyeyim - yeniden giriş saldırıları akıllı sözleşmelerin sessiz katilleri. Aldatıcı bir şekilde basit ama yıkıcı derecede etkili. Gelin bunların ne olduğunu ve fonlarınızı tüketmeden önce nasıl durdurabileceğimizi inceleyelim.
İlk kez bir reentrancy zayıflığıyla karşılaştığımda, birinin bu kadar masum görünen bir kod parçasını nasıl istismar edebileceğini anlamaya çalışarak saatlerce uyku kaybettim. Kavram sinir bozucu bir şekilde basit: bir sözleşme, ilk yürütme tamamlanmadan önce başka birine geri çağrı yapabilir.
Bunu hayal edin: ContractA'nın 10 ETH'si var ve ContractB buna 1 ETH yatırdı. ContractB fonlarını çektiğinde, ContractA, B'nin bakiyesini sıfıra güncellemeden önce ETH'yi gönderir. Bu küçük sıralama hatası büyük bir güvenlik açığı yaratır.
Ne oluyor? Kötü niyetli sözleşmenin geri çağırma fonksiyonu hemen withdraw()'i tekrar çağırıyor ve bakiye henüz güncellenmediği için bakiye kontrolünden tekrar geçiyor! Bu döngü, ContractA tamamen boşalana kadar tekrarlanır. Kötü değil mi?
İşte bir saldırganın bunu kodda nasıl istismar ettiğine dair:
// Saldırı sözleşmesi çağrıları withdraw() // ContractA ETH gönderir bu fallback() tetikler. // fallback(), bakiye güncellenmeden önce withdraw()'i tekrar çağırır. // Durumlar çalınana kadar durulayıp tekrarlayın
Milyonlarca kaybeden projelere tanık oldum çünkü bu basit saldırı vektörünü anlamadılar. Hala bu acemi hatasını yapan birçok geliştiricinin olması beni öfkelendiriyor.
Sözleşmelerinizi Korumanın Üç Tekniği
nonReentrant Modifikatörü
Bu, yürütme sırasında sözleşmeyi kilitler ve bu düzenleyiciyle işaretlenmiş herhangi bir işlevin yeniden girilmesini engeller. Basit ama etkili.
Kontroller-Etkiler-Etkileşimler Deseni
Bu benim kişisel favorim. Yerine:
// HASSAS require(balance > 0); send(ether); bakiye = 0;
Bunu yap:
// GÜVENLİ require(balance > 0); bakiye = 0; // Durumu dış etkileşimlerden ÖNCE güncelle send(ether);
Her zaman ETH veya token göndermeden önce durumunuzu güncelleyin!
GlobalReentrancyGuard
Birden fazla etkileşimli sözleşmeye sahip projeler için, bu, paylaşılan bir kilitleme mekanizması kullanarak tüm sözleşme ekosisteminizde koruma sağlar.
Bu teknikler sadece akademik değil - sayısız projeyi tamamen mali iflastan kurtardı.
Çok sayıda geliştirici hâlâ "bana olmaz" diye düşünüyor ve bu korumaları atlıyor. O kişi olma. ETH veya token gönderen her bir fonksiyon, bu koruma mekanizmalarından en az birini uygulamalıdır.
Unutmayın, akıllı sözleşme geliştirmede paranoya bir özellik, hata değildir. Kaçırılan bir koruma her şeyi kaybettirebilir.