Analisis Penolakan Layanan Serangan dalam Smart Contract
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:
Kekurangan dalam logika kontrak, seperti kompleksitas perhitungan dari beberapa fungsi publik yang terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.
Ketergantungan pada status eksekusi kontrak eksternal saat memanggil kontrak lintas, eksekusi kontrak eksternal yang tidak dapat diandalkan dapat menghambat operasi normal kontrak ini.
Faktor manusia, seperti pemilik kontrak kehilangan kunci pribadi yang mengakibatkan beberapa fungsi hak istimewa tidak dapat dipanggil.
Berikut adalah analisis tentang kerentanan 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 register_account(&mut self) {
jika self.accounts.insert(&env::predecessor_account_id(), &0).is_some() {
env::panic('Akun sudah terdaftar'.to_string().as_bytes());
}else{
self.registered.push(env::predecessor_account_id());
}
log!('Akun terdaftar{}',env::predecessor_account_id());
}
pub fn distribute_token(&mut self, amount: u128) {
assert_eq!(env::predecessor_account_id(),DISTRIBUTOR,'ERR_NOT_ALLOWED');
untuk cur_account dalam self.registered.iter(){
let balance = self.accounts.get(&cur_account).expect('ERR_GET');
self.accounts.insert(&cur_account,&balance.checked_add(amount).expect('ERR_ADD'));
log!('Tidak dapat mendistribusikan ke akun{}',&cur_account);
ext_ft_token::ft_transfer(
cur_account.clone(),
jumlah,
&FTTOKEN,
0,
GAS_FOR_SINGLE_CALL
);
}
}
Masalah pada kontrak ini adalah ukuran array self.registered tidak dibatasi, dapat dikendalikan oleh pengguna jahat sehingga menjadi terlalu besar, yang mengakibatkan konsumsi Gas yang melebihi batas saat menjalankan fungsi distribute_token.
Rekomendasi solusi:
Batasi panjang maksimum array self.registered
Menggunakan mode penarikan, tidak secara aktif mendistribusikan hadiah, tetapi membiarkan pengguna memanggil fungsi penarikan sendiri.
2. Ketergantungan Status Lintas Kontrak Menyebabkan Kontrak Terblokir
Masalah dengan kontrak ini adalah, jika akun pengguna dengan tawaran tertinggi saat ini dibatalkan dalam kontrak token eksternal, tawaran baru yang lebih tinggi tidak akan dapat mengembalikan token dari tawaran sebelumnya, yang menyebabkan proses lelang terhambat.
Solusi:
Pertimbangkan kemungkinan kegagalan panggilan kontrak eksternal, implementasikan penanganan kesalahan yang wajar. Misalnya, menyimpan token yang tidak dapat dikembalikan sementara di dalam kontrak, kemudian memperbolehkan pengguna untuk menariknya sendiri.
3. Kunci privat pemilik kontrak hilang
Dalam kontrak pintar sering terdapat fungsi privilese yang hanya dapat dieksekusi oleh pemilik. 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
Menggunakan mekanisme multisignature sebagai pengganti kontrol hak milik tunggal
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.
15 Suka
Hadiah
15
7
Bagikan
Komentar
0/400
consensus_whisperer
· 23jam yang lalu
Kontrak yang tidak terampil dan suka bermain, siapa yang kamu maksud?
Lihat AsliBalas0
RumbleValidator
· 07-30 19:13
Sekali lagi melihat kerentanan loop mati yang sederhana, sebelum kontrak melakukan dump, pengujian beban pada node harus dilakukan hingga batas maksimal.
Lihat AsliBalas0
GasGuzzler
· 07-30 19:12
Ahli mengurangkan biaya GAS! Langsung meledak
Lihat AsliBalas0
BtcDailyResearcher
· 07-30 19:10
Ada lagi yang tertipu oleh DoS, sangat lucu
Lihat AsliBalas0
SignatureDenied
· 07-30 19:05
Sudah diserang lagi? Siapa yang masih berani menyimpan Kunci Pribadi sembarangan?
Lihat AsliBalas0
DefiOldTrickster
· 07-30 19:02
Lao Bai bermain di pasar beruang sampai terampil, tapi dia terkunci kontrak karena kehilangan Kunci Pribadi. Crispy.
Lihat AsliBalas0
RuntimeError
· 07-30 18:53
Hmm? Apakah kontrak bisa mati karena kehilangan Kunci Pribadi? Sungguh membuat cemas ya.
Kedalaman analisis terhadap kerentanan serangan DoS dalam smart contract dan strategi pencegahannya
Analisis Penolakan Layanan Serangan dalam Smart Contract
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:
Kekurangan dalam logika kontrak, seperti kompleksitas perhitungan dari beberapa fungsi publik yang terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.
Ketergantungan pada status eksekusi kontrak eksternal saat memanggil kontrak lintas, eksekusi kontrak eksternal yang tidak dapat diandalkan dapat menghambat operasi normal kontrak ini.
Faktor manusia, seperti pemilik kontrak kehilangan kunci pribadi yang mengakibatkan beberapa fungsi hak istimewa tidak dapat dipanggil.
Berikut adalah analisis tentang kerentanan 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, }
pub fn register_account(&mut self) { jika self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic('Akun sudah terdaftar'.to_string().as_bytes()); }else{ self.registered.push(env::predecessor_account_id()); } log!('Akun terdaftar{}',env::predecessor_account_id()); }
pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(),DISTRIBUTOR,'ERR_NOT_ALLOWED'); untuk cur_account dalam self.registered.iter(){ let balance = self.accounts.get(&cur_account).expect('ERR_GET'); self.accounts.insert(&cur_account,&balance.checked_add(amount).expect('ERR_ADD')); log!('Tidak dapat mendistribusikan ke akun{}',&cur_account); ext_ft_token::ft_transfer( cur_account.clone(), jumlah, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL ); } }
Masalah pada kontrak ini adalah ukuran array self.registered tidak dibatasi, dapat dikendalikan oleh pengguna jahat sehingga menjadi terlalu besar, yang mengakibatkan konsumsi Gas yang melebihi batas saat menjalankan fungsi distribute_token.
Rekomendasi solusi:
2. Ketergantungan Status Lintas Kontrak Menyebabkan Kontrak Terblokir
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 }
PromiseOrValue { assert!(jumlah > 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!) 'pemimpin_saat_ini: {} tawaran_tertinggi: {}', self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }
#( pub fn account_resolve)&mut self,sender_id: AccountId,amount: u128[private] { cocok env::promise_result(0) { PromiseResult::NotReady => unreachable!(), PromiseResult::Successful(_) => { ext_ft_token::ft_transfer( self.current_leader.clone)(, self.highest_bid, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; self.current_leader = sender_id; self.highest_bid = amount; } PromiseResult::Failed => { ext_ft_token::ft_transfer) sender_id.clone)(, jumlah, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; log!)'Kembali Sekarang'); } }; }
Masalah dengan kontrak ini adalah, jika akun pengguna dengan tawaran tertinggi saat ini dibatalkan dalam kontrak token eksternal, tawaran baru yang lebih tinggi tidak akan dapat mengembalikan token dari tawaran sebelumnya, yang menyebabkan proses lelang terhambat.
Solusi:
Pertimbangkan kemungkinan kegagalan panggilan kontrak eksternal, implementasikan penanganan kesalahan yang wajar. Misalnya, menyimpan token yang tidak dapat dikembalikan sementara di dalam kontrak, kemudian memperbolehkan pengguna untuk menariknya sendiri.
3. Kunci privat pemilik kontrak hilang
Dalam kontrak pintar sering terdapat fungsi privilese yang hanya dapat dieksekusi oleh pemilik. Jika kunci pribadi pemilik hilang, fungsi-fungsi ini tidak akan dapat dipanggil, yang dapat menyebabkan kontrak tidak berfungsi dengan baik.
Solusi: