Analyse approfondie des vulnérabilités d'attaque DoS dans les smart contracts et des stratégies de prévention

Analyse des attaques par déni de service dans les smart contracts

attaque par déni de service(DoS)peut entraîner une incapacité d'utilisation normale des smart contracts pendant un certain temps, voire de manière permanente. Les principales raisons incluent :

  1. Les défauts dans la logique des contrats, comme une complexité de calcul trop élevée pour certaines fonctions publiques, entraînant une consommation de Gas dépassant les limites.

  2. La dépendance à l'état d'exécution des contrats externes lors des appels inter-contrats, l'exécution des contrats externes peu fiable peut bloquer le fonctionnement normal de ce contrat.

  3. Facteurs humains, comme la perte de la clé privée par le propriétaire du contrat, empêchant l'appel de certaines fonctions privilégiées.

Voici une analyse des vulnérabilités des attaques DoS dans les smart contracts à travers des exemples concrets.

1. Parcourir des structures de données volumineuses modifiables par des tiers

Voici un contrat simple utilisé pour "distribuer des dividendes" aux utilisateurs enregistrés :

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

pub fn register_account(&mut self) { si self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic('Le compte est déjà enregistré'.to_string().as_bytes()); }else{ self.registered.push(env::predecessor_account_id()); } log!('Compte enregistré{}',env::predecessor_account_id()); }

pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(),DISTRIBUTEUR,'ERR_NOT_ALLOWED'); pour cur_account dans 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!('Tenter de distribuer au compte{}',&cur_account); ext_ft_token::ft_transfer( cur_account.clone(), montant, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL ); } }

Le problème de ce contrat est que la taille du tableau self.registered n'est pas limitée, ce qui peut être manipulé par des utilisateurs malveillants pour devenir trop grand, entraînant une consommation de Gas dépassant la limite lors de l'exécution de la fonction distribute_token.

Solutions recommandées:

  1. Limiter la longueur maximale du tableau self.registered.
  2. Utiliser le mode de retrait, sans parcourir activement la distribution des récompenses, mais en laissant les utilisateurs appeler eux-mêmes la fonction de retrait.

2. La dépendance d'état entre contrats entraîne un blocage des contrats

Considérer un contrat de "enchères" :

rouille #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, pub current_leader: AccountId, pub highest_bid: u128, pub remboursement: bool }

PromiseOrValue { assert!(amount > self.highest_bid); si self.current_leader == DEFAULT_ACCOUNT { self.current_leader = sender_id; self.highest_bid = amount; } sinon { 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, montant, &env::current_account_id((, 0, GAS_FOR_SINGLE_CALL * 3, (); } log!) 'leader_actuel: {} enchère_maximale: {}', 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)(, montant, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, (; log!)'Revenir en arrière maintenant'); } }; }

Le problème avec ce contrat est que si le compte de l'utilisateur avec la meilleure enchère actuelle est annulé dans un contrat de jeton externe, une nouvelle enchère plus élevée ne pourra pas retourner les jetons de l'enchérisseur précédent, ce qui bloquera le processus d'enchères.

Méthode de résolution:

Considérer les cas où les appels de contrats externes peuvent échouer, mettre en œuvre un traitement des erreurs raisonnable. Par exemple, stocker temporairement les jetons non remboursables dans le contrat, puis permettre aux utilisateurs de les retirer eux-mêmes par la suite.

3. Clé privée du propriétaire du contrat perdue

Dans les smart contracts, il existe souvent des fonctions à privilège qui ne peuvent être exécutées que par le propriétaire. Si la clé privée du propriétaire est perdue, ces fonctions ne pourront pas être appelées, ce qui pourrait entraîner un fonctionnement anormal du contrat.

Méthode de résolution :

  1. Configurer plusieurs propriétaires de contrats pour une gouvernance partagée
  2. Adopter un mécanisme de multi-signature pour remplacer le contrôle d'accès d'un seul propriétaire
  3. Mettre en œuvre des solutions de gouvernance de contrat décentralisé

</accountid,balance></accountid,>

Voir l'original
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
  • Récompense
  • 7
  • Partager
Commentaire
0/400
consensus_whisperervip
· Il y a 23h
Quel contrat à la fois mauvais et amusant parles-tu ?
Voir l'originalRépondre0
RumbleValidatorvip
· 07-30 19:13
Encore un simple exploit de boucle infinie, la validation des nœuds pour le dump du contrat doit être poussée à ses limites.
Voir l'originalRépondre0
GasGuzzlervip
· 07-30 19:12
Expert en dissuasion des frais de GAS ! Explosion directe
Voir l'originalRépondre0
BtcDailyResearchervip
· 07-30 19:10
Encore quelqu'un a été piégé par DoS, mort de rire.
Voir l'originalRépondre0
SignatureDeniedvip
· 07-30 19:05
Encore attaqué ? Qui oserait encore stocker sa clé privée n'importe comment ?
Voir l'originalRépondre0
DefiOldTrickstervip
· 07-30 19:02
Le vieux blanc a joué à fond dans le marché baissier, puis un contrat a été verrouillé par une clé privée perdue. Peau fragile.
Voir l'originalRépondre0
RuntimeErrorvip
· 07-30 18:53
Hmm ? Un contrat peut-il être détruit juste parce qu'on a perdu la clé privée ? C'est vraiment urgent.
Voir l'originalRépondre0
Trader les cryptos partout et à tout moment
qrCode
Scan pour télécharger Gate app
Communauté
Français (Afrique)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)