Rust akıllı sözleşmeler güvenliği: hizmet reddi saldırısına karşı savunma
hizmet reddi saldırısı(DoS) saldırıları, akıllı sözleşmelerin bir süre boyunca normal bir şekilde kullanılamamasına veya hatta kalıcı olarak devre dışı kalmasına neden olabilir. Başlıca nedenler şunlardır:
Sözleşme mantığında hesaplama karmaşıklığına bağlı bir hata var, bu da Gas tüketiminin sınırları aşmasına neden oluyor.
Diğer akıllı sözleşmelerin çağrılması sırasında dış akıllı sözleşmelerin yürütme durumu üzerinde bağımlılık, dış akıllı sözleşmeler tarafından engellenebilir.
Sözleşme sahibi özel anahtarını kaybederse, kritik ayrıcalık işlevlerini yerine getiremez.
Aşağıda somut örneklerle analiz yapılacaktır.
1. Dışarıdan kontrol edilebilen büyük veri yapılarında gezinmekten kaçının
Aşağıda bir "temettü" akıllı sözleşmesi bulunmaktadır, DoS riski mevcuttur:
pas
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Sözleşme {
pub kayıtlı: Vec,
pub accounts: UnorderedMap<accountid, balance="">,
}
for cur_account in 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!("Hesaba {} dağıtmaya çalışın", &cur_account);
ext_ft_token::ft_transfer(
cur_account.clone(),
miktar,
&FTTOKEN,
0,
TEKÇAĞRI İÇİN GAZ
);
}
}
Bu sözleşmenin sorunu, registered dizisinin boyutunun bir sınırı olmaması, kötü niyetli kullanıcılar tarafından kontrol edilerek çok büyük hale getirilebilir, bu da distribute_token fonksiyonunun Gas tüketiminin sınırı aşmasına neden olur.
Bu sözleşmenin sorunlarından biri, önceki en yüksek teklif sahibinin hesabını iptal etmesi durumunda, yeni teklif verenlerin durumu başarılı bir şekilde güncelleyememesidir.
Çözüm, makul bir hata yönetimi uygulamaktır; örneğin, geri alınamayan tokenleri geçici olarak depolamak, daha sonra kullanıcı tarafından alınmasını sağlamak.
pas
pub struct Sözleşme {
// ...
pub kayıp_bulunan: UnorderedMap<accountid, balance="">,
}
pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) {
eşleşme env::promise_result(0) {
PromiseResult::Successful(_) => {
// Normal iade mantığı
}
PromiseResult::Başarısız => {
// Geri alınamayacak tokenler geçici olarak saklanacak
let lost_amount = self.lost_found.get(&self.current_leader).unwrap_or(0);
self.lost_found.insert(&self.current_leader, &)kayıp_miktar + self.highest_bid((;
// Durumu güncelle
self.current_leader = sender_id;
self.en yüksek teklif = amount;
}
PromiseResult::NotReady => ulaşılamaz!)),
}
}
pub fn withdraw_lost_found(&mut self) {
let account = env::predecessor_account_id();
let amount = self.lost_found.get(&account).unwrap_or(0);
eğer miktar > 0 {
self.lost_found.insert(&account, &0);
ext_ft_token::ft_transfer(hesap, miktar, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL);
}
}
3. Tek nokta arızasından kaçınma
Sözleşme sahibinin özel anahtarının kaybolması, kritik ayrıcalık işlevlerinin kullanılamamasına neden olur. Çözüm, çoklu imza mekanizmasının benimsenmesidir:
pas
pub struct Sözleşme {
pub sahipleri: Vec\u003caccountid\u003e,
gerekli_onaylar: u64,
pub işlemler: Vec,
}
let transaction = &mut self.transactions[transaction_id as usize];
transaction.onaylar += 1;
eğer işlem.onayları >= self.gerekli_onaylar {
self.execute_transaction)transaction_id);
}
}
fn execute_transaction(&mut self, transaction_id: u64) {
let transaction = self.transactions.remove(transaction_id as usize);
// İşlem mantığını yürüt
}
Çoklu imza mekanizması sayesinde, tek bir sahibi anahtarının kaybolmasının neden olduğu sözleşme çökmesini önleyebilir, sözleşmenin merkeziyetsizliğini ve güvenliğini artırır.
</accountid,></accountid,balance></accountid,>
View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
7 Likes
Reward
7
6
Share
Comment
0/400
TokenomicsTherapist
· 19h ago
Özel Anahtar'ı kaybetmek çok gerçekçi haha
View OriginalReply0
GasFeeNightmare
· 08-04 04:49
不愧是Gas Büyük Yatırımcılar
View OriginalReply0
PretendingToReadDocs
· 08-04 04:49
DoS'dan kaçış yok, başka hangi güvenlikten bahsedebiliriz?
View OriginalReply0
HashRatePhilosopher
· 08-04 04:32
rust ordusu geliyor, rakip titresin.
View OriginalReply0
TestnetFreeloader
· 08-04 04:28
防dos sen burada bu tuzak teorisini mi kullanıyorsun
Rust akıllı sözleşmeler güvenliği: 3 büyük anahtar strateji DoS saldırılarına karşı savunma
Rust akıllı sözleşmeler güvenliği: hizmet reddi saldırısına karşı savunma
hizmet reddi saldırısı(DoS) saldırıları, akıllı sözleşmelerin bir süre boyunca normal bir şekilde kullanılamamasına veya hatta kalıcı olarak devre dışı kalmasına neden olabilir. Başlıca nedenler şunlardır:
Sözleşme mantığında hesaplama karmaşıklığına bağlı bir hata var, bu da Gas tüketiminin sınırları aşmasına neden oluyor.
Diğer akıllı sözleşmelerin çağrılması sırasında dış akıllı sözleşmelerin yürütme durumu üzerinde bağımlılık, dış akıllı sözleşmeler tarafından engellenebilir.
Sözleşme sahibi özel anahtarını kaybederse, kritik ayrıcalık işlevlerini yerine getiremez.
Aşağıda somut örneklerle analiz yapılacaktır.
1. Dışarıdan kontrol edilebilen büyük veri yapılarında gezinmekten kaçının
Aşağıda bir "temettü" akıllı sözleşmesi bulunmaktadır, DoS riski mevcuttur:
pas #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Sözleşme { pub kayıtlı: Vec, pub accounts: UnorderedMap<accountid, balance="">, }
pub fn register_account(&mut self) { eğer self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic("Hesap zaten kayıtlı".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("Kayıtlı hesap {}", env::önceki_hesap_id()); }
pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(), DAĞITICI, "ERR_NOT_ALLOWED");
}
Bu sözleşmenin sorunu, registered dizisinin boyutunun bir sınırı olmaması, kötü niyetli kullanıcılar tarafından kontrol edilerek çok büyük hale getirilebilir, bu da distribute_token fonksiyonunun Gas tüketiminin sınırı aşmasına neden olur.
Önerilen çözüm "çekim" modunu benimsemektir:
pas pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(), DAĞITICI, "ERR_NOT_ALLOWED");
}
pub fn withdraw(&mut self) { let account = env::predecessor_account_id(); let amount = self.accounts.get(&account).unwrap(); self.accounts.insert(&account, &0);
}
2. Diğer sözleşmelere bağlı durum çağrılarından kaçının
Aşağıda bir "ihale" akıllı sözleşme örneği bulunmaktadır:
pas #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Sözleşme { pub kayıtlı: Vec, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, mevcut_lider: HesapId, en yüksek teklif: u128, }
PromiseOrValue { assert!(miktar > self.en yüksek teklif);
}
#( pub fn account_resolve)&mut self, sender_id: AccountId, amount: u128[private] { match env::promise_result(0) { PromiseResult::Başarılı(_) => { 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::Başarısız => { ext_ft_token::ft_transfer) sender_id.clone)(, miktar, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; log!)"Şimdi Geri Dön"); } PromiseResult::NotReady => unreachable!(), }; }
Bu sözleşmenin sorunlarından biri, önceki en yüksek teklif sahibinin hesabını iptal etmesi durumunda, yeni teklif verenlerin durumu başarılı bir şekilde güncelleyememesidir.
Çözüm, makul bir hata yönetimi uygulamaktır; örneğin, geri alınamayan tokenleri geçici olarak depolamak, daha sonra kullanıcı tarafından alınmasını sağlamak.
pas pub struct Sözleşme { // ... pub kayıp_bulunan: UnorderedMap<accountid, balance="">, }
pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) { eşleşme env::promise_result(0) { PromiseResult::Successful(_) => { // Normal iade mantığı } PromiseResult::Başarısız => { // Geri alınamayacak tokenler geçici olarak saklanacak let lost_amount = self.lost_found.get(&self.current_leader).unwrap_or(0); self.lost_found.insert(&self.current_leader, &)kayıp_miktar + self.highest_bid((;
}
pub fn withdraw_lost_found(&mut self) { let account = env::predecessor_account_id(); let amount = self.lost_found.get(&account).unwrap_or(0); eğer miktar > 0 { self.lost_found.insert(&account, &0); ext_ft_token::ft_transfer(hesap, miktar, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL); } }
3. Tek nokta arızasından kaçınma
Sözleşme sahibinin özel anahtarının kaybolması, kritik ayrıcalık işlevlerinin kullanılamamasına neden olur. Çözüm, çoklu imza mekanizmasının benimsenmesidir:
pas pub struct Sözleşme { pub sahipleri: Vec\u003caccountid\u003e, gerekli_onaylar: u64, pub işlemler: Vec, }
pub fn propose_transaction(&mut self, transaction: Transaction) { assert!(self.owners.contains)&env::predecessor_account_id(((, "Sahip değil"); self.transactions.push)transaction); }
pub fn confirm_transaction(&mut self, transaction_id: u64) { assert!(self.owners.contains)&env::predecessor_account_id(((, "Sahip değil");
}
fn execute_transaction(&mut self, transaction_id: u64) { let transaction = self.transactions.remove(transaction_id as usize); // İşlem mantığını yürüt }
Çoklu imza mekanizması sayesinde, tek bir sahibi anahtarının kaybolmasının neden olduğu sözleşme çökmesini önleyebilir, sözleşmenin merkeziyetsizliğini ve güvenliğini artırır.