Akıllı Sözleşmelerde Yeniden Giriş Saldırıları: Kapsamlı Önleme Kılavuzu

Reentrancy saldırıları, akıllı sözleşme güvenliğinde en önemli zafiyetlerden birini temsil eder. Bu makale, reentrancy saldırılarının detaylı teknik analizini sağlar, kod örnekleri aracılığıyla mekanizmalarını gösterir ve akıllı sözleşmelerinizi korumak için üç sınanmış önleme tekniği sunar.

Yeniden Girişin Anlaşılması: Temel Kavram

Temelinde, bir reentrancy saldırısı, bir sözleşme (ContractB), ilk fonksiyon çağrısı tamamlanmadan önce çağrılan sözleşmeye (ContractA) geri çağırdığında meydana gelir. Bu zayıflık, fonksiyon çağrılarının rekürsif bir döngüsünü oluşturarak fonları boşaltmak veya sözleşme durumunu manipüle etmek için sömürülebilir.

Ana fikir: Yeniden giriş zafiyetleri, bir sözleşme iç durumunu güncellemeden önce dış çağrılar yaptığında ortaya çıkar.

Bu senaryoyu düşünün:

  • ContractA'nın bakiyesinde 10 ETH var
  • ContractB, ContractA'ya 1 ETH yatırdı.
  • ContractA'nın savunmasız bir çekim fonksiyonu var.

ContractB bu güvenlik açığını kullandığında, herhangi bir bakiye güncellemesi gerçekleşmeden önce ContractA'nın fonlarını boşaltmak için bir dizi özyinelemeli çağrı gerçekleştirebilir.

Yeniden Giriş Saldırısının Anatomisi

Saldırı deseni genellikle iki temel bileşenden oluşur:

  1. Saldırı() fonksiyonu istismarı başlatır
  2. ETH alındığında çalışan bir geri çağırma() fonksiyonu, döngü oluşturur.

Saldırı aşağıdaki sırayla gerçekleştirilir:

  1. Saldırgan, kötü niyetli sözleşmelerinde attack()'i çağırır
  2. Kötü niyetli sözleşme, savunmasız sözleşmede withdraw() çağrısını yapar.
  3. Savunmasız sözleşme, geri alma fonksiyonunu tetikleyerek saldırgana ETH gönderir.
  4. Geri dönüş işlevi içinde, saldırgan withdraw()'i tekrar olarak çağırır.
  5. Bu döngü, savunmasız sözleşmenin fonları tükenene kadar tekrarlanır

Tarihsel önemi: 2016'daki ünlü DAO hack'i, yaklaşık $60 milyon değerinde ETH kaybıyla sonuçlanan, yüksek profilli bir yeniden giriş saldırısıydı ve nihayetinde Ethereum sert çatalına yol açtı.

Hassas Kod Analizi

Hassas bir sözleşme uygulamasını inceleyelim:

solidity kontrat EtherStore { mapping(address => uint) public balances;

function deposit() public payable {
    balances[msg.sender] += msg.value;
}

function withdrawAll() public {
    uint bal = balances[msg.sender];
    require(bal > 0);
    
    (bool sent, ) = msg.sender.call{value: bal}("");
    require(gönderildi, "Ether gönderimi başarısız oldu");
    
    balances[msg.sender] = 0;
}

}

Bu koddaki kritik zafiyet, sözleşmenin göndericinin bakiyesini güncellemeden önce ETH (msg.sender.call{value: bal}("")) göndermesidir. Bu sıra, yeniden giriş zafiyetini yaratır.

Açığın İstismar Edilmesi

Bir saldırgan, EtherStore'daki zayıflıktan yararlanmak için böyle bir sözleşmeyi dağıtacaktır:

solidity sözleşme Attack { EtherStore halka açık etherStore;

constructor(address _etherStoreAddress) {
    etherStore = EtherStore(_etherStoreAddress);
}

// Geri dönüş fonksiyonu - EtherStore Ether gönderdiğinde çağrılır
fallback() harici ödenecek {
    if (address)etherStore(.balance >= 1 ether( {
        etherStore.withdrawAll));
    }
}

function attack() external payable {
    require(msg.value >= 1 ether);
    etherStore.deposit{value: 1 ether}();
    etherStore.withdrawAll();
}

}

Saldırı akışı:

  1. Saldırgan attack()'i arar, 1 ETH yatırır
  2. Saldırgan EtherStore üzerinde withdrawAll() çağrısını yapar
  3. EtherStore 1 ETH geri gönderir, fallback fonksiyonunu tetikler.
  4. Geri dönüş fonksiyonu içinde, saldırgan withdrawAll()'i tekrar özyinelemeli olarak çağırır.
  5. Bakiyenin henüz güncellenmemiş olması nedeniyle, bu döngü EtherStore boşalana kadar devam eder.

Yeniden Girişe Karşı Üç Savunma Tekniği

( 1. Fonksiyon Düzeyinde Koruma: noReentrant Modifikatörü

Bu değiştirici, bir işlevin hala yürütülürken yeniden girişini önleyen bir kilit mekanizması oluşturur:

solidity sözleşme ReentrancyGuard { bool private locked = false;

modifier noReentrant)### {
    require(!locked, "Reentrant call");
    kilitli = true;
    _;
    kilitli = false;
}

}

kontrat SecureEtherStore ReentrancyGuard'dır { mapping(address => uint) public balances;

function withdrawAll() public noReentrant {
    uint bal = balances[msg.sender];
    require(bal > 0);
    
    (bool sent, ) = msg.sender.call{value: bal}("");
    require(sent, "Ether gönderme işlemi başarısız oldu");
    
    balances[msg.sender] = 0;
}

}

Teknik analiz: Değiştirici, yeniden girişimi önlemek için bir durum değişkenini (locked) olarak ayarlar. Bu değiştiriciye sahip bir fonksiyon, zaten çalışırken çağrılırsa, işlem geri alınacaktır.

( 2. Çapraz Fonksiyon Koruması: Kontroller-Etkiler-Etkileşimler Deseni

Bu desen, dış etkileşimlerden önce durum değişikliklerinin gerçekleşmesini sağlayarak çapraz işlevli yeniden giriş sorununu ele alır:

solidity // HASSAS function withdrawAll)### public { uint bal = balances[msg.sender]; require(bal > 0);

(bool sent, ) = msg.sender.call{value: bal}("");
require(gönderildi, "Ether gönderimi başarısız");

balances[msg.sender] = 0; // Durum, harici çağrıdan SONRA güncellendi

}

// GÜVENLİ function withdrawAll() public { uint bal = balances[msg.sender]; require(bal > 0);

balances[msg.sender] = 0; // Durum, harici çağrıdan ÖNCE güncellendi

(bool sent, ) = msg.sender.call{value: bal}("");
require(sent, "Ether gönderme başarısız");

}

Teknik analiz: Dış çağrılardan önce durum değişkenlerini güncelleyerek, sözleşme reentrancy'yi etkinleştirse bile, durumun zaten düzgün bir şekilde değiştirilmiş olmasını sağlar, bu da kötüye kullanımı önler.

( 3. Sözleşmeler Arası Koruma: GlobalReentrancyGuard

Birden fazla etkileşimde bulunan sözleşmelere sahip projeler için, küresel yeniden girdi koruyucusu uygulamak sistem genelinde koruma sağlar:

solidity sözleşme GlobalReentrancyGuard { bool özel _notEntered;

constructor)### {
    _notEntered = true;
}

modifier globalNonReentrant() {
    require(_notEntered, "ReentrancyGuard: reentrant call");
    _notEntered = false;
    _;
    _notEntered = true;
}

}

sözleşme ContractA, GlobalReentrancyGuard { fonksiyon transferFunds() public globalNonReentrant { // Güvenli uygulama } }

sözleşme ContractB GlobalReentrancyGuard { function withdrawFunds() public globalNonReentrant { // Güvenli uygulama } }

Teknik analiz: Bu yaklaşım, aynı ekosistemdeki birden fazla sözleşme arasında yeniden girişin önlenmesi için paylaşılan bir sözleşme durumunu kullanır ve sadece fonksiyon seviyesinde değil, sistem seviyesinde koruma sunar.

Güvenlik En İyi Uygulamaları Uygulama Matrisi

| Önleme Tekniği | Koruma Seviyesi | Gaz Maliyeti | Uygulama Karmaşıklığı | En İyi | |----------------------|------------------|----------|---------------------------|----------| | noReentrant Modifier | Fonksiyon seviyesi | Düşük-Orta | Basit | Tek hassas fonksiyonlar | | Kontroller-Etkiler-Etkileşimler | Sözleşme seviyesi | Düşük | Orta | Genel sözleşme güvenliği | | GlobalReentrancyGuard | Sistem seviyesi | Orta | Karmaşık | Çoklu sözleşme sistemleri |

Teknik Uygulama Hususları

Reentrancy koruması uygularken, geliştiricilerin dikkate alması gerekenler:

  1. Gaz optimizasyonu: Yeniden giriş korumaları, işlev yürütmesine ek yük getirir. Yüksek frekanslı işlemlerde performans etkisini dikkate alın.

  2. Sıra dışı durumlar: Bazı meşru kullanım senaryoları reentrant davranış gerektirir. Koruma mekanizmalarınızın beklenen işlevselliği bozmadığından emin olun.

  3. Denetim gereksinimi: Koruma mekanizmaları mevcut olsa bile, profesyonel güvenlik denetimleri daha karmaşık güvenlik açıklarını tespit etmek için hala gereklidir.

  4. Koruma kapsamı: Farklı yeniden giriş koruma mekanizmaları, farklı saldırı vektörlerine hitap eder. Sözleşmenizin belirli zayıflıklarını anlamak, uygun koruma seçimi için çok önemlidir.

Reentrancy saldırılarının mekanizmalarını anlayarak ve uygun koruma mekanizmalarını uygulayarak, geliştiriciler akıllı sözleşmelerinin blockchain ekosistemindeki en yaygın ve tehlikeli güvenlik açıklarından birine karşı güvenliğini önemli ölçüde artırabilirler.

IN0.18%
View Original
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.
  • Reward
  • Comment
  • Repost
  • Share
Comment
0/400
No comments
  • Pin
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate App
Community
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)