Versi Singkat: Reentrancy seperti seorang hacker yang memanggil Anda kembali saat Anda masih mentransfer uang kepada mereka—mereka menguras dompet Anda sebelum transaksi selesai.
Inilah kebenaran yang brutal: Lebih dari $100M telah hilang akibat eksploitasi reentrancy. Yang paling terkenal? Peretasan DAO (2016) mencuri $50M dalam ETH dengan mengeksploitasi kerentanan ini.
Bagaimana Serangan Bekerja (Menggunakan Logika Kode Sebenarnya)
Bayangkan ContractA memiliki 10 ETH dan ContractB memiliki saldo 1 ETH yang disimpan di dalamnya.
Ketika ContractB memanggil withdrawAll(), inilah yang seharusnya terjadi:
Cek saldo > 0 ✓
Kirim ETH kembali ✓
Perbarui saldo menjadi 0 ✓
Tapi di sinilah masalahnya: Penyerang memanfaatkan urutan operasi.
Alur Eksploitasi:
Penyerang memanggil attack() → yang memanggil withdrawAll() di ContractA
ContractA mengirim 1 ETH dan memicu fungsi fallback penyerang()
Sebelum saldo diperbarui menjadi 0, fallback() segera memanggil withdrawAll() lagi
ContractA memeriksa: “Apakah saldo > 0?” YA ( karena belum diperbarui!)
Mengirim lagi 1 ETH → memicu fallback() lagi
Ini berulang sampai ContractA sepenuhnya terhabiskan
Wawasan kunci: Pembaruan saldo terjadi SETELAH transfer ETH. Itu adalah jendela kerentanan.
Tiga Strategi Pertahanan
1. Modifier nonReentrant ( Perlindungan Fungsi Tunggal )
Kunci fungsi saat sedang dieksekusi. Tidak diizinkan masuk kembali:
solidity
modifier nonReentrant {
require(!locked, “No reentrancy”);
terkunci = true;
_;
terkunci = false;
}
Sederhana, tetapi hanya melindungi satu fungsi pada satu waktu.
2. Pola Pemeriksaan-Dampak-Interaksi ( Perlindungan Multi-Fungsi )
Ini adalah pengubah permainan:
Pemeriksaan: Verifikasi kondisi (balance > 0)
Efek: Perbarui status (balance = 0) ← Pindahkan ini SEBELUM mengirim ETH
Untuk sistem kompleks dengan beberapa kontrak yang saling berinteraksi, gunakan kontrak penjaga terpusat yang melacak status kunci di semua kontrak. Ketika ContractA memanggil ContractB, penjaga mencatatnya—jika ContractB mencoba untuk memanggil kembali ke dalam sistem sebelum mengembalikan, penjaga memblokirnya.
Mengapa Ini Penting
Rentrancy bukan hanya masalah Solidity—ini adalah masalah desain. Setiap kali Anda mengirim ETH atau memanggil fungsi eksternal, Anda menyerahkan kontrol kepada kode yang tidak tepercaya. Fungsi fallback penyerang dijalankan dalam konteks KONTRAK Anda.
Data tersebut: Chainalysis menemukan bahwa ~60% dari eksploitasi bernilai tinggi pada 2023-2024 melibatkan reentrancy atau pola serupa. Proyek teratas seperti Yearn, Curve, dan Balancer semuanya mengalami ketakutan reentrancy.
Kesimpulan: Gunakan Checks-Effects-Interactions secara default. Tambahkan nonReentrant di mana diperlukan. Untuk sistem multi-kontrak, terapkan GlobalReentrancyGuard. Kerugian lebih dari $100M seharusnya bisa dihindari dengan pola dasar ini.
Ikuti @TheBlockChainer untuk lebih banyak penyelaman mendalam tentang keamanan Web3.
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.
Serangan Reentrancy: Mengapa Smart Contract Terus Terbongkar (Dan Cara Menghentikannya)
Versi Singkat: Reentrancy seperti seorang hacker yang memanggil Anda kembali saat Anda masih mentransfer uang kepada mereka—mereka menguras dompet Anda sebelum transaksi selesai.
Inilah kebenaran yang brutal: Lebih dari $100M telah hilang akibat eksploitasi reentrancy. Yang paling terkenal? Peretasan DAO (2016) mencuri $50M dalam ETH dengan mengeksploitasi kerentanan ini.
Bagaimana Serangan Bekerja (Menggunakan Logika Kode Sebenarnya)
Bayangkan ContractA memiliki 10 ETH dan ContractB memiliki saldo 1 ETH yang disimpan di dalamnya.
Ketika ContractB memanggil withdrawAll(), inilah yang seharusnya terjadi:
Tapi di sinilah masalahnya: Penyerang memanfaatkan urutan operasi.
Alur Eksploitasi:
Wawasan kunci: Pembaruan saldo terjadi SETELAH transfer ETH. Itu adalah jendela kerentanan.
Tiga Strategi Pertahanan
1. Modifier nonReentrant ( Perlindungan Fungsi Tunggal )
Kunci fungsi saat sedang dieksekusi. Tidak diizinkan masuk kembali: solidity modifier nonReentrant { require(!locked, “No reentrancy”); terkunci = true; _; terkunci = false; }
Sederhana, tetapi hanya melindungi satu fungsi pada satu waktu.
2. Pola Pemeriksaan-Dampak-Interaksi ( Perlindungan Multi-Fungsi )
Ini adalah pengubah permainan:
Pesanan salah:
require(balance > 0); → kirim ETH → saldo = 0; // Terlambat!
Urutan yang benar:
require(balance > 0); → saldo = 0; // Perbarui PERTAMA → kirim ETH // Kemudian berinteraksi
Sekarang bahkan jika fallback() masuk kembali, saldo sudah 0. Serangan gagal.
3. GlobalReentrancyGuard (Perlindungan Lintas Kontrak)
Untuk sistem kompleks dengan beberapa kontrak yang saling berinteraksi, gunakan kontrak penjaga terpusat yang melacak status kunci di semua kontrak. Ketika ContractA memanggil ContractB, penjaga mencatatnya—jika ContractB mencoba untuk memanggil kembali ke dalam sistem sebelum mengembalikan, penjaga memblokirnya.
Mengapa Ini Penting
Rentrancy bukan hanya masalah Solidity—ini adalah masalah desain. Setiap kali Anda mengirim ETH atau memanggil fungsi eksternal, Anda menyerahkan kontrol kepada kode yang tidak tepercaya. Fungsi fallback penyerang dijalankan dalam konteks KONTRAK Anda.
Data tersebut: Chainalysis menemukan bahwa ~60% dari eksploitasi bernilai tinggi pada 2023-2024 melibatkan reentrancy atau pola serupa. Proyek teratas seperti Yearn, Curve, dan Balancer semuanya mengalami ketakutan reentrancy.
Kesimpulan: Gunakan Checks-Effects-Interactions secara default. Tambahkan nonReentrant di mana diperlukan. Untuk sistem multi-kontrak, terapkan GlobalReentrancyGuard. Kerugian lebih dari $100M seharusnya bisa dihindari dengan pola dasar ini.
Ikuti @TheBlockChainer untuk lebih banyak penyelaman mendalam tentang keamanan Web3.