Analisis Kerentanan DoS pada Smart Contract Rust: Iterasi Berulang, Ketergantungan Antar Kontrak, dan Desain Izin

robot
Pembuatan abstrak sedang berlangsung

Analisis Kerentanan Serangan DoS dalam Kontrak Pintar Rust

Serangan DoS (Denial of Service) dapat menyebabkan smart contract tidak dapat digunakan dengan normal untuk jangka waktu tertentu atau bahkan secara permanen. Penyebab utama termasuk:

  1. Terdapat cacat dalam logika kontrak. Misalnya, beberapa fungsi publik yang diimplementasikan tidak mempertimbangkan kompleksitas perhitungan, yang mengakibatkan konsumsi Gas melebihi batas.

  2. Ketergantungan pada status eksekusi kontrak eksternal saat memanggil kontrak lintas. Eksekusi kontrak eksternal yang tidak dapat diandalkan dapat menyebabkan kontrak ini terblokir.

  3. Faktor manusia, seperti pemilik kontrak kehilangan kunci pribadi, menyebabkan status sistem penting tidak dapat diperbarui tepat waktu.

Berikut adalah analisis tentang kerentanan serangan DoS melalui contoh konkret.

1. Melakukan iterasi pada struktur data besar yang dapat diubah dari luar

Berikut adalah kontrak sederhana untuk "dividen" bagi 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 di 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!("Coba distribusikan ke akun {}", &cur_account);
    
    ext_ft_token::ft_transfer(
        cur_account.clone(),
        jumlah,
        &FTTOKEN,
        0,
        GAS_FOR_SINGLE_CALL
    );
}

}

Data status kontrak ini self.registered tidak memiliki batasan ukuran, dapat dimanipulasi oleh pengguna jahat sehingga menjadi terlalu besar. Hal ini menyebabkan eksekusi distribute_token gagal karena konsumsi Gas melebihi batas.

Disarankan untuk beralih ke mode penarikan: Pihak kontrak terlebih dahulu mencatat, pengguna dapat mengambil kembali hadiah mereka sendiri melalui fungsi withdraw. Kontrak hanya perlu memelihara jumlah hadiah pengguna tunggal.

2. Ketergantungan status antar kontrak yang 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!(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!)
    "pemimpin_saat_ini: {} tawaran_tertinggi: {}", 
    self.current_leader,
    self.highest_bid
);

PromiseOrValue::Value(0)

}

Logika kontrak ini bergantung pada pengembalian token dari penawar tertinggi sebelumnya untuk memperbarui tawaran tertinggi yang baru. Jika akun penawar sebelumnya telah dinonaktifkan, tawaran baru akan terblokir.

Solusi: Pertimbangkan kemungkinan kegagalan dalam panggilan eksternal, tambahkan penanganan kesalahan. Token yang tidak dapat dikembalikan dapat disimpan sementara, kemudian pengguna dapat menariknya sendiri.

3. Kehilangan kunci pribadi pemilik

Beberapa fungsi kontrak diatur hanya dapat dijalankan oleh pemilik, untuk mengubah variabel sistem yang penting. Jika pemilik tidak dapat menjalankan fungsinya ( seperti kehilangan kunci pribadi ), fungsi-fungsi ini tidak akan dapat digunakan, yang dapat menyebabkan kontrak menjadi tidak berfungsi.

Solusi:

  • Mengatur beberapa pemilik untuk pemerintahan bersama
  • Menggunakan skema multi-tanda tangan sebagai pengganti kontrol izin pemilik tunggal
  • Mewujudkan mekanisme pemerintahan terdesentralisasi

Desain izin yang wajar dan mekanisme tata kelola dapat secara efektif mengurangi risiko titik kegagalan tunggal dan meningkatkan ketahanan kontrak.

</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
  • 7
  • Bagikan
Komentar
0/400
MEVHunterLuckyvip
· 07-17 08:49
Iterasi berulang memanggil super berbahaya sebelumnya kehilangan
Lihat AsliBalas0
BridgeNomadvip
· 07-15 16:21
melihat vektor serangan yang persis ini di bsc bulan lalu... kapan para pengembang akan belajar smh
Lihat AsliBalas0
BearMarketSurvivorvip
· 07-14 20:00
Kode medan perang pahlawan kembali, kerugian perang untung ada posisi manajemen di
Lihat AsliBalas0
BearMarketSurvivorvip
· 07-14 19:57
Kunci Pribadi hilang, bagaimana ini? Sangat panik.
Lihat AsliBalas0
FlatlineTradervip
· 07-14 19:56
Desain kontrak sejelek ini masih dikeluarkan
Lihat AsliBalas0
MetaverseVagrantvip
· 07-14 19:54
Bug ini memiliki tingkat bahaya yang agak tinggi.
Lihat AsliBalas0
HodlVeteranvip
· 07-14 19:34
Satu lihat saja sudah jelas bahwa itu adalah pelajaran pahit dari Veteran Kripto yang mengalami kegagalan...
Lihat AsliBalas0
  • 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)