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:

  1. Logika kontrak memiliki cacat, seperti kompleksitas perhitungan dari beberapa fungsi yang terlalu tinggi, menyebabkan konsumsi Gas melebihi batas.

  2. Dalam pemanggilan antar kontrak, pelaksanaan kontrak bergantung pada status kontrak eksternal, yang mungkin diblokir oleh kontrak eksternal.

  3. 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()); }

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

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) }

#(
pub fn account_resolve)&mut self, sender_id: AccountId, amount: u128[private] {
    match 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!)"Kembalikan tawaran saat ini");
        }
    };
}

}

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.
  • Hadiah
  • 8
  • Bagikan
Komentar
0/400
WhaleWatchervip
· 07-20 17:14
Kontrak hanya akan diserang jika itu adalah saringan, bukan?
Lihat AsliBalas0
CryptoSourGrapevip
· 07-20 17:08
Jika saya tahu celah ini lebih awal, mengapa saya harus terpuruk sampai sekarang dan setiap hari menceritakan kesedihan?
Lihat AsliBalas0
PancakeFlippavip
· 07-18 18:19
Kontrak juga memiliki ambang batas, siapa yang menyuruhmu memiliki keterampilan yang buruk.
Lihat AsliBalas0
LazyDevMinervip
· 07-17 19:29
Soal menulis kode dibahas lagi di kehidupan berikutnya 8
Lihat AsliBalas0
NftPhilanthropistvip
· 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
Lihat AsliBalas0
just_another_walletvip
· 07-17 19:20
Masalah keamanan harus diperhatikan, teman-teman.
Lihat AsliBalas0
NFTragedyvip
· 07-17 19:16
Masalah ini, kode-nya belum selesai ditulis...
Lihat AsliBalas0
HalfBuddhaMoneyvip
· 07-17 19:01
Astaga, harus menambal lagi, kontrak sampah.
Lihat AsliBalas0
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)