Pindai untuk Mengunduh Aplikasi Gate
qrCode
Opsi Unduhan Lainnya
Jangan ingatkan saya lagi hari ini

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:

  1. Cek saldo > 0 ✓
  2. Kirim ETH kembali ✓
  3. 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
  • Interaksi: Kirim ETH

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.

ETH0.17%
CRV-2.54%
BAL1.45%
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)