Memahami Serangan Reentrancy & Cara Mencegahnya ๐Ÿ”

robot
Pembuatan abstrak sedang berlangsung

Serangan reentrancy tampaknya rumit pada awalnya. Izinkan saya menjelaskannya dalam istilah sederhana dan tampilkan beberapa cara untuk menjaga smart contract Anda tetap aman ๐Ÿ›ก๏ธ

Apa itu Serangan Reentrancy? ๐Ÿง

Ini terjadi ketika ContractB memanggil kembali ke ContractA sementara ContractA masih berjalan. Hal yang buruk. Penyerang menyukai kerentanan ini untuk menguras dana dari kontrak ๐Ÿ’ธ

Bayangkan ini:

  • ContractA memegang 10 ETH
  • ContractB menempatkan 1 ETH
  • ContractB kemudian mencuri segalanya

Mekanisme Serangan ๐Ÿ•ต๏ธโ€โ™‚๏ธ

Anda memerlukan dua hal kunci:

  1. attack() fungsi untuk memulainya semua
  2. fallback() fungsi untuk bagian licik

Alur berjalan seperti:

  1. ContractB memulai serangan() yang memanggil withdraw() dari ContractA
  2. ContractA memeriksa saldo ContractB
  3. ContractA mengirim ETH ke ContractB
  4. Ini memicu fallback ContractB()
  5. Loop berlanjut. Uang hilang ๐Ÿšจ

Sangat mengejutkan betapa sederhana namun menghancurkannya ini.

Contoh Kode Rentan ๐Ÿ“

Inilah tampilan kontrak yang rentan: solidity fungsi withdrawAll() publik { uint bal = balances[msg.sender]; require(bal > 0);

(bool sent, ) = msg.sender.call{value: bal}("");
require(sent, "Gagal mengirim Ether");

balances[msg.sender] = 0; // Mengupdate SETELAH mengirim? Kesalahan besar!

}

Kontrak serangan melakukan ini: solidity fallback() eksternal dapat dibayar { jika ( etherStore.balance >= 1 ether ) etherStore.withdrawAll(); }

fungsi attack() eksternal dapat dibayar { require(msg.value >= 1 ether); etherStore.deposit{value: 1 ether}(); etherStore.withdrawAll(); }

Tiga Cara untuk Menghentikan Serangan Ini ๐Ÿ›ก๏ธ

1. nonReentrant Modifier ๐Ÿ”’

solidity bool private locked = false;

modifier nonReentrant() { require(!locked, "Tidak ada reentrancy"); terkunci = true; _; kunci = false; }

Tambahkan ke fungsi yang rentan. Sederhana tetapi efektif.

2. Pola Cek-Dampak-Interaksi ๐Ÿ“Š

Ini sangat penting:

solidity fungsi withdrawAll() publik { uint bal = balances[msg.sender]; require(bal > 0);

balances[msg.sender] = 0; // Perbarui PERTAMA

(bool sent, ) = msg.sender.call{value: bal}(""); // KEMUDIAN interaksi
require(sent, "Gagal mengirim Ether");

}

Perbarui status Anda terlebih dahulu. Berinteraksi kemudian. Selalu.

3. Perlindungan Global ๐ŸŒ

Untuk proyek yang lebih besar:

solidity kontrak GlobalReentrancyGuard { bool private locked = false;

modifier globalNonReentrant() {
    require(!locked, "Tidak ada reentrancy");
    terkunci = true;
    _;
    terkunci = false;
}

}

Biarkan semua kontrak Anda mewarisi ini. Ekosistem yang lebih aman.

Tren Terbaru ๐Ÿ”ฅ

Pada September 2025, serangan ini masih mengganggu DeFi. Tidak sepenuhnya jelas mengapa pengembang terus melakukan kesalahan yang sama. Alat seperti Slither dapat mendeteksi masalah ini. Echidna dan Foundry membantu mengujinya ๐Ÿš€

Keamanan bukan hanya tentang menambahkan modifikasi. Ini adalah pola pikir.

Tetap waspada di luar sana! ๐Ÿ›ก๏ธ

ETH3.1%
Lihat Asli
Halaman ini mungkin berisi konten pihak ketiga, yang disediakan untuk tujuan informasi saja (bukan pernyataan/jaminan) dan tidak boleh dianggap sebagai dukungan terhadap pandangannya oleh Gate, atau sebagai nasihat keuangan atau profesional. Lihat Penafian untuk detailnya.
  • Hadiah
  • Komentar
  • Posting ulang
  • Bagikan
Komentar
0/400
Tidak ada komentar
  • Sematkan
Perdagangkan Kripto Di Mana Saja Kapan Saja
qrCode
Pindai untuk mengunduh aplikasi Gate
Komunitas
Bahasa Indonesia
  • ็ฎ€ไฝ“ไธญๆ–‡
  • English
  • Tiแบฟng Viแป‡t
  • ็น้ซ”ไธญๆ–‡
  • Espaรฑol
  • ะ ัƒััะบะธะน
  • Franรงais (Afrique)
  • Portuguรชs (Portugal)
  • Bahasa Indonesia
  • ๆ—ฅๆœฌ่ชž
  • ุจุงู„ุนุฑุจูŠุฉ
  • ะฃะบั€ะฐั—ะฝััŒะบะฐ
  • Portuguรชs (Brasil)