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 :
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.
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.
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 :
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:
Limiter la longueur maximale du tableau self.registered.
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
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 :
Configurer plusieurs propriétaires de contrats pour une gouvernance partagée
Adopter un mécanisme de multi-signature pour remplacer le contrôle d'accès d'un seul propriétaire
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.
15 J'aime
Récompense
15
7
Partager
Commentaire
0/400
consensus_whisperer
· Il y a 23h
Quel contrat à la fois mauvais et amusant parles-tu ?
Voir l'originalRépondre0
RumbleValidator
· 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
GasGuzzler
· 07-30 19:12
Expert en dissuasion des frais de GAS ! Explosion directe
Voir l'originalRépondre0
BtcDailyResearcher
· 07-30 19:10
Encore quelqu'un a été piégé par DoS, mort de rire.
Voir l'originalRépondre0
SignatureDenied
· 07-30 19:05
Encore attaqué ? Qui oserait encore stocker sa clé privée n'importe comment ?
Voir l'originalRépondre0
DefiOldTrickster
· 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
RuntimeError
· 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.
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 :
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.
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.
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:
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 :