Attaque par déni de service dans les smart contracts Rust
attaque par déni de service(DoS) peut entraîner des smart contracts étant incapables de fonctionner correctement pendant une période de temps ou même de manière permanente. Les principales raisons incluent :
La logique du contrat présente des défauts, comme une complexité de calcul trop élevée pour certaines fonctions, entraînant une consommation de Gas dépassant la limite.
Dans les appels inter-contrats, l'exécution du contrat dépend de l'état des contrats externes et peut être bloquée par des contrats externes.
Facteurs humains, tels que la perte de la clé privée par le propriétaire du contrat, entraînant l'incapacité d'appeler les fonctions privilégiées.
Voici une analyse des vulnérabilités d'attaque par déni de service dans les smart contracts à travers des exemples concrets.
1. Parcourir de manière itérative de grandes structures de données modifiables par des sources externes
Voici un simple contrat pour distribuer des dividendes aux utilisateurs inscrits :
impl Contrat {
pub fn register_account(&mut self) {
if 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!("enregistrer le compte {}", env::predecessor_account_id());
}
pub fn distribute_token(&mut self, amount: u128) {
assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "Pas de droit d'opérer");
pour compte dans self.registered.iter() {
let balance = self.accounts.get(&account).expect("获取失败");
self.accounts.insert(\u0026account, \u0026balance.checked_add(amount).expect("加法溢出"));
log!("Essayer de distribuer au compte {}", &account);
ext_ft_token::ft_transfer(
account.clone(),
montant,
&FTTOKEN,
0,
GAS_FOR_SINGLE_CALL
);
}
}
}
Le problème de ce contrat est que la taille du tableau registered n'est pas limitée, ce qui permet à des utilisateurs malveillants de le manipuler pour qu'il devienne trop grand, entraînant une consommation de Gas excessive pour la fonction distribute_token.
Solutions recommandées:
Reconcevoir le contrat en mode de retrait. Permettre aux utilisateurs d'appeler activement la fonction de retrait pour obtenir des récompenses, le contrat n'a besoin que d'enregistrer le montant des récompenses que l'utilisateur peut retirer.
2. La dépendance d'état entre contrats entraîne un blocage
Le problème du contrat est le suivant : il est nécessaire de retourner avec succès les jetons de l'enchérisseur précédent pour pouvoir mettre à jour l'enchère la plus élevée. Si l'enchérisseur précédent a annulé son compte, le contrat ne pourra pas effectuer le remboursement et sera bloqué.
Solution :
Considérer les cas où les appels de contrats externes peuvent échouer et mettre en œuvre un traitement des erreurs raisonnable. Il est possible de garder temporairement les jetons non remboursables dans le contrat, puis de permettre aux utilisateurs de les retirer activement par la suite.
3. Perte de la clé privée du propriétaire du contrat
Certaines fonctions de contrat sont définies comme uniquement exécutables par le propriétaire, pour modifier des variables système critiques. Si la clé privée du propriétaire est perdue, ces fonctions ne pourront pas être appelées, ce qui pourrait entraîner un dysfonctionnement du contrat.
Solution :
Mettre en place plusieurs propriétaires de contrat pour une gouvernance conjointe, ou adopter un mécanisme de multi-signatures pour remplacer le contrôle des permissions d'un seul propriétaire, afin de réaliser une gouvernance décentralisée.
</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.
16 J'aime
Récompense
16
8
Partager
Commentaire
0/400
WhaleWatcher
· 07-20 17:14
Un contrat est une passoire, n'est-ce pas ?
Voir l'originalRépondre0
CryptoSourGrape
· 07-20 17:08
Si j'avais su cette faille plus tôt, pourquoi devrais-je tomber à vendre ma misère tous les jours maintenant.
Voir l'originalRépondre0
PancakeFlippa
· 07-18 18:19
Les contrats ont aussi des seuils, n'est-ce pas ? Qui vous a dit que vos compétences étaient faibles ?
Voir l'originalRépondre0
LazyDevMiner
· 07-17 19:29
On parlera de coder dans la prochaine vie 8
Voir l'originalRépondre0
NftPhilanthropist
· 07-17 19:28
en fait... *boit du thé* un autre contrat peu efficace en gas qui pourrait être optimisé pour un impact social. quand les développeurs comprendront-ils l'importance des pratiques de codage réfléchies smh
Voir l'originalRépondre0
just_another_wallet
· 07-17 19:20
Les frères doivent vraiment prendre au sérieux les problèmes de sécurité.
Voir l'originalRépondre0
NFTragedy
· 07-17 19:16
Ce problème, eh bien, le code n'est même pas terminé...
Voir l'originalRépondre0
HalfBuddhaMoney
· 07-17 19:01
Je suis désolé, je dois encore combler des lacunes dans ce contrat poubelle.
Analyse des vulnérabilités des attaques DoS sur les smart contracts Rust et solutions
Attaque par déni de service dans les smart contracts Rust
attaque par déni de service(DoS) peut entraîner des smart contracts étant incapables de fonctionner correctement pendant une période de temps ou même de manière permanente. Les principales raisons incluent :
La logique du contrat présente des défauts, comme une complexité de calcul trop élevée pour certaines fonctions, entraînant une consommation de Gas dépassant la limite.
Dans les appels inter-contrats, l'exécution du contrat dépend de l'état des contrats externes et peut être bloquée par des contrats externes.
Facteurs humains, tels que la perte de la clé privée par le propriétaire du contrat, entraînant l'incapacité d'appeler les fonctions privilégiées.
Voici une analyse des vulnérabilités d'attaque par déni de service dans les smart contracts à travers des exemples concrets.
1. Parcourir de manière itérative de grandes structures de données modifiables par des sources externes
Voici un simple contrat pour distribuer des dividendes aux utilisateurs inscrits :
rouille #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }
impl Contrat { pub fn register_account(&mut self) { if 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!("enregistrer le compte {}", env::predecessor_account_id()); }
}
Le problème de ce contrat est que la taille du tableau registered n'est pas limitée, ce qui permet à des utilisateurs malveillants de le manipuler pour qu'il devienne trop grand, entraînant une consommation de Gas excessive pour la fonction distribute_token.
Solutions recommandées:
Reconcevoir le contrat en mode de retrait. Permettre aux utilisateurs d'appeler activement la fonction de retrait pour obtenir des récompenses, le contrat n'a besoin que d'enregistrer le montant des récompenses que l'utilisateur peut retirer.
2. La dépendance d'état entre contrats entraîne un blocage
Considérez un contrat d'enchères :
rouille #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec\u003caccountid\u003e, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, pub current_leader: AccountId, pub highest_bid: u128, pub refund: bool }
impl Contrat { PromiseOrValue { assert!(amount > self.highest_bid); if 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, montant, &env::current_account_id((, 0, GAS_FOR_SINGLE_CALL * 3, (); } log!) "Enchérisseur actuel: {} Meilleure enchère: {}", self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }
}
Le problème du contrat est le suivant : il est nécessaire de retourner avec succès les jetons de l'enchérisseur précédent pour pouvoir mettre à jour l'enchère la plus élevée. Si l'enchérisseur précédent a annulé son compte, le contrat ne pourra pas effectuer le remboursement et sera bloqué.
Solution :
Considérer les cas où les appels de contrats externes peuvent échouer et mettre en œuvre un traitement des erreurs raisonnable. Il est possible de garder temporairement les jetons non remboursables dans le contrat, puis de permettre aux utilisateurs de les retirer activement par la suite.
3. Perte de la clé privée du propriétaire du contrat
Certaines fonctions de contrat sont définies comme uniquement exécutables par le propriétaire, pour modifier des variables système critiques. Si la clé privée du propriétaire est perdue, ces fonctions ne pourront pas être appelées, ce qui pourrait entraîner un dysfonctionnement du contrat.
Solution :
Mettre en place plusieurs propriétaires de contrat pour une gouvernance conjointe, ou adopter un mécanisme de multi-signatures pour remplacer le contrôle des permissions d'un seul propriétaire, afin de réaliser une gouvernance décentralisée.