Panduan Praktis Pencegahan Serangan DoS pada Kontrak Pintar Rust

Rust smart contract pengembangan jurnal: pencegahan denial-of-service attack

Penolakan layanan ( DoS ) serangan dapat menyebabkan smart contract tidak dapat digunakan dengan normal untuk jangka waktu tertentu atau bahkan secara permanen. Penyebab umum termasuk:

  1. Masalah kompleksitas perhitungan dalam logika kontrak, menyebabkan konsumsi Gas melebihi batas.

  2. Ketika memanggil kontrak lintas, ketergantungan yang tidak tepat pada status eksekusi kontrak eksternal menyebabkan kontrak ini terblokir.

  3. Kunci pribadi pemilik kontrak hilang, menyebabkan fungsi hak istimewa tidak dapat dipanggil, status sistem penting tidak dapat diperbarui.

Berikut adalah analisis tentang celah serangan DoS dan solusi-solusinya melalui beberapa contoh konkret.

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

Berikut adalah kontrak "dividen" sederhana, yang memiliki risiko DoS:

karat #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }

impl Contract { 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(\u0026cur_account, \u0026balance.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
        );
    }
}

}

Masalahnya adalah ukuran array registered tidak terbatas, dapat dikendalikan oleh pengguna jahat sehingga menjadi terlalu besar, menyebabkan konsumsi Gas saat fungsi distribute_token dijalankan melebihi batas.

Saran solusi:

  1. Batasi ukuran array registered.

  2. Mengadopsi mode "penarikan", memungkinkan pengguna untuk mengambil hadiah sendiri, bukan kontrak yang secara aktif mendistribusikannya.

2. Ketergantungan Status Lintas Kontrak Mengakibatkan Pemblokiran Kontrak

Berikut adalah contoh kontrak "bidding":

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 Contract { 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!)
        "current_leader: {} highest_bid: {}", 
        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!)"Return Back Now");
        }
    };
}

}

Masalahnya adalah pembaruan status kontrak bergantung pada pemanggilan kontrak eksternal. Jika akun penawar tertinggi sebelumnya telah dibatalkan, penawar berikutnya tidak akan dapat memperbarui status.

Saran solusi:

Pertimbangkan kemungkinan kegagalan panggilan eksternal, implementasikan mekanisme penanganan kesalahan yang wajar. Misalnya, menyimpan token yang tidak dapat dikembalikan sementara di dalam kontrak, kemudian memungkinkan pengguna untuk menariknya secara sukarela.

3. Kunci pribadi pemilik hilang

Banyak kontrak memiliki fungsi istimewa yang hanya dapat dieksekusi oleh pemilik. Jika kunci pribadi pemilik hilang, fungsi-fungsi ini tidak dapat dipanggil, yang dapat menyebabkan kontrak tidak berfungsi dengan baik.

Saran solusi:

  1. Mengatur beberapa pemilik kontrak untuk mengelola bersama.

  2. Menggunakan mekanisme tanda tangan ganda untuk menggantikan kontrol pemilik tunggal.

  3. Mewujudkan mekanisme tata kelola kontrak yang terdesentralisasi.

Dengan langkah-langkah di atas, risiko serangan penolakan layanan dalam kontrak pintar dapat secara efektif dikurangi, meningkatkan keamanan dan keandalan 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
  • 8
  • Bagikan
Komentar
0/400
MEVHunterWangvip
· 6jam yang lalu
Bermain buruk dengan kontrak masih bisa diatur dengan mudah.
Lihat AsliBalas0
ProofOfNothingvip
· 10jam yang lalu
Ini adalah formalitas yang hanya dibicarakan di atas kertas.
Lihat AsliBalas0
LuckyHashValuevip
· 14jam yang lalu
Serangan tidak dapat dicegah, sekarang harus turun ke nol lagi.
Lihat AsliBalas0
ColdWalletGuardianvip
· 14jam yang lalu
Pengetahuan dasar standar untuk memulai Blockchain
Lihat AsliBalas0
SelfSovereignStevevip
· 14jam yang lalu
Kunci Pribadi hilang akan menjadi bencana.
Lihat AsliBalas0
StableBoivip
· 14jam yang lalu
Risiko kontrak ini memang agak banyak, stabilitasnya tidak terlalu baik.
Lihat AsliBalas0
Ser_This_Is_A_Casinovip
· 14jam yang lalu
Ah~Rust sangat sulit, lebih baik mempertimbangkan Solidity
Lihat AsliBalas0
GasFeeThundervip
· 14jam yang lalu
gas makan terlalu banyak dan bikin masalah? Cepat atau lambat kontrak akan dibersihkan
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)