Rust smart contract dalam denial-of-service attack
denial-of-service attack ( DoS ) dapat menyebabkan smart contract tidak dapat digunakan dengan normal untuk jangka waktu tertentu atau bahkan secara permanen. Alasan utamanya termasuk:
Logika kontrak memiliki cacat, seperti kompleksitas perhitungan dari beberapa fungsi yang terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.
Dalam pemanggilan antar kontrak, pelaksanaan kontrak bergantung pada status kontrak eksternal, yang mungkin diblokir oleh kontrak eksternal.
Faktor manusia, seperti pemilik kontrak kehilangan kunci pribadi, menyebabkan fungsi privilese tidak dapat dipanggil.
Berikut ini menganalisis celah serangan DoS dalam smart contract melalui contoh konkret.
1. Melakukan iterasi pada struktur data besar yang dapat dimodifikasi dari luar
Berikut adalah kontrak sederhana untuk memberikan dividen kepada pengguna terdaftar:
pub fn distribute_token(&mut self, amount: u128) {
assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "tidak memiliki hak untuk beroperasi");
untuk akun di self.registered.iter() {
let balance = self.accounts.get(&account).expect("获取失败");
self.accounts.insert(&account, &balance.checked_add(amount).expect("penambahan overflow"));
log!("Mencoba mendistribusikan ke akun {}", &account);
ext_ft_token::ft_transfer(
account.clone(),
jumlah,
&FTTOKEN,
0,
GAS_FOR_SINGLE_CALL
);
}
}
}
Masalah dari kontrak tersebut adalah ukuran array registered tidak dibatasi, sehingga dapat dimanipulasi oleh pengguna jahat menjadi terlalu besar, yang mengakibatkan konsumsi Gas yang terlalu tinggi pada fungsi distribute_token.
Rekomendasi solusi:
Mengadopsi model penarikan untuk membangun kembali kontrak. Membiarkan pengguna secara aktif memanggil fungsi penarikan untuk mendapatkan hadiah, kontrak hanya perlu mencatat jumlah hadiah yang dapat ditarik oleh pengguna.
2. Ketergantungan Status Lintas Kontrak yang Mengakibatkan Pemblokiran
Masalah dari kontrak ini adalah: token dari penawar sebelumnya harus berhasil dikembalikan untuk dapat memperbarui tawaran tertinggi. Jika penawar sebelumnya membatalkan akunnya, kontrak tidak dapat menyelesaikan pengembalian dana dan akan terblokir.
Solusi:
Pertimbangkan kemungkinan kegagalan panggilan kontrak eksternal dan implementasikan penanganan kesalahan yang wajar. Token yang tidak dapat dikembalikan dapat disimpan sementara dalam kontrak, dan selanjutnya pengguna diizinkan untuk menarik secara aktif.
3. Kehilangan kunci privat pemilik kontrak
Beberapa fungsi kontrak diatur untuk hanya dapat dijalankan oleh pemilik, digunakan untuk mengubah variabel sistem yang penting. Jika kunci pribadi pemilik hilang, fungsi-fungsi ini tidak akan dapat dipanggil, yang dapat menyebabkan kontrak tidak berfungsi dengan baik.
Solusi:
Mengatur beberapa pemilik kontrak untuk pemerintahan bersama, atau menggunakan mekanisme tanda tangan ganda sebagai pengganti kontrol hak pemilik tunggal, untuk mencapai pemerintahan terdesentralisasi.
</accountid,balance></accountid,>
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.
16 Suka
Hadiah
16
8
Bagikan
Komentar
0/400
WhaleWatcher
· 07-20 17:14
Kontrak hanya akan diserang jika itu adalah saringan, bukan?
Lihat AsliBalas0
CryptoSourGrape
· 07-20 17:08
Jika saya tahu celah ini lebih awal, mengapa saya harus terpuruk sampai sekarang dan setiap hari menceritakan kesedihan?
Lihat AsliBalas0
PancakeFlippa
· 07-18 18:19
Kontrak juga memiliki ambang batas, siapa yang menyuruhmu memiliki keterampilan yang buruk.
Lihat AsliBalas0
LazyDevMiner
· 07-17 19:29
Soal menulis kode dibahas lagi di kehidupan berikutnya 8
Lihat AsliBalas0
NftPhilanthropist
· 07-17 19:28
sebenarnya... *menyeruput teh* kontrak yang tidak efisien gas lainnya yang bisa dioptimalkan untuk dampak sosial. kapan para pengembang akan belajar tentang praktik pengkodean yang bijaksana smh
Analisis dan Solusi Kerentanan DoS pada Smart Contract Rust
Rust smart contract dalam denial-of-service attack
denial-of-service attack ( DoS ) dapat menyebabkan smart contract tidak dapat digunakan dengan normal untuk jangka waktu tertentu atau bahkan secara permanen. Alasan utamanya termasuk:
Logika kontrak memiliki cacat, seperti kompleksitas perhitungan dari beberapa fungsi yang terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.
Dalam pemanggilan antar kontrak, pelaksanaan kontrak bergantung pada status kontrak eksternal, yang mungkin diblokir oleh kontrak eksternal.
Faktor manusia, seperti pemilik kontrak kehilangan kunci pribadi, menyebabkan fungsi privilese tidak dapat dipanggil.
Berikut ini menganalisis celah serangan DoS dalam smart contract melalui contoh konkret.
1. Melakukan iterasi pada struktur data besar yang dapat dimodifikasi dari luar
Berikut adalah kontrak sederhana untuk memberikan dividen kepada pengguna terdaftar:
karat #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub terdaftar: Vec, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }
impl Kontrak { pub fn register_account(&mut self) { jika self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic("Akun telah terdaftar".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("daftar akun {}", env::predecessor_account_id()); }
}
Masalah dari kontrak tersebut adalah ukuran array registered tidak dibatasi, sehingga dapat dimanipulasi oleh pengguna jahat menjadi terlalu besar, yang mengakibatkan konsumsi Gas yang terlalu tinggi pada fungsi distribute_token.
Rekomendasi solusi:
Mengadopsi model penarikan untuk membangun kembali kontrak. Membiarkan pengguna secara aktif memanggil fungsi penarikan untuk mendapatkan hadiah, kontrak hanya perlu mencatat jumlah hadiah yang dapat ditarik oleh pengguna.
2. Ketergantungan Status Lintas Kontrak yang Mengakibatkan Pemblokiran
Pertimbangkan sebuah kontrak lelang:
karat #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub terdaftar: Vec, pub bid_price: UnorderedMap<accountid,balance>, pub current_leader: AccountId, pub highest_bid: u128, pub refund: bool }
impl Kontrak { PromiseOrValue { assert!(amount > self.highest_bid); jika self.current_leader == DEFAULT_ACCOUNT { self.current_leader = sender_id; self.highest_bid = amount; } else { ext_ft_token::account_exist( self.current_leader.clone)(, &FTTOKEN, 0, env::prepaid_gas() - GAS_FOR_SINGLE_CALL * 4, (.then)ext_self::account_resolve) sender_id, jumlah, &env::current_account_id((, 0, GAS_FOR_SINGLE_CALL * 3, (); } log!) "Penawar tertinggi saat ini: {} Tawaran tertinggi: {}", self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }
}
Masalah dari kontrak ini adalah: token dari penawar sebelumnya harus berhasil dikembalikan untuk dapat memperbarui tawaran tertinggi. Jika penawar sebelumnya membatalkan akunnya, kontrak tidak dapat menyelesaikan pengembalian dana dan akan terblokir.
Solusi:
Pertimbangkan kemungkinan kegagalan panggilan kontrak eksternal dan implementasikan penanganan kesalahan yang wajar. Token yang tidak dapat dikembalikan dapat disimpan sementara dalam kontrak, dan selanjutnya pengguna diizinkan untuk menarik secara aktif.
3. Kehilangan kunci privat pemilik kontrak
Beberapa fungsi kontrak diatur untuk hanya dapat dijalankan oleh pemilik, digunakan untuk mengubah variabel sistem yang penting. Jika kunci pribadi pemilik hilang, fungsi-fungsi ini tidak akan dapat dipanggil, yang dapat menyebabkan kontrak tidak berfungsi dengan baik.
Solusi:
Mengatur beberapa pemilik kontrak untuk pemerintahan bersama, atau menggunakan mekanisme tanda tangan ganda sebagai pengganti kontrol hak pemilik tunggal, untuk mencapai pemerintahan terdesentralisasi.