Bug de réutilisation des adresses du portefeuille Samourai | par Shinobi [SHI256]

Bug de réutilisation des adresses du portefeuille Samourai | par Shinobi [SHI256]
Shinobi [SHI256]

Le 12 juin de cette année, j’ai été approché par un utilisateur de Samourai Wallet qui avait remarqué plusieurs cas de réutilisation d’adresses dans son portefeuille. Selon cet utilisateur, le comportement s’est produit automatiquement plusieurs fois sans aucune intervention manuelle de sa part. Ces instances affichaient un modèle de la même adresse réutilisée à chaque fois que la réutilisation se produisait. Après avoir posé quelques questions supplémentaires à l’utilisateur, il a été confirmé que l’adresse de son portefeuille réutilisée était spécifiquement le chemin de dérivation d’index 0 pour ce type d’adresse. C’était particulier et je soupçonnais que le problème principal était lié à la façon dont le client gérait l’indexation des adresses les plus récemment utilisées.

Après mon enquête, j’ai contacté un développeur de Samourai à propos du problème et nous avons convenu d’une date de divulgation fixée au 15 juillet, soit exactement un mois plus tard. Bien qu’ils aient eux-mêmes révélé certains aspects du problème hier, je souhaite néanmoins donner ma version du problème. Voici des extraits mot pour mot de la divulgation que j’ai faite au développeur de Samourai, avec des explications supplémentaires.

Je suis presque sûr d’avoir une idée de la cause, et c’est un problème pour les utilisateurs de votre backend ou pour les instances Dojo, car le problème peut être causé à la fois par des erreurs de connexion réseau ou par des données incorrectes du backend.

https://code.samourai.io/wallet/samourai-wallet-android/-/blob/develop/app/src/main/java/com/samourai/wallet/send/SendFactory.java#L694 Cette fonction ici est captivante un index pour les adresses de changement, mais cela dépend de la valeur de l’index dans la fabrique d’adresses. Je pense que cela vient de l’API Factory, par exemple ici : https://code.samourai.io/wallet/samourai-wallet-android/-/blob/develop/app/src/main/java/com/samourai/ portefeuille/api/APIFactory.java#L2607

Il semble que setHighestPostChangeIdx ne soit appelé depuis API Factory que si la requête HTTP réussit et que le corps de la réponse est un JSON valide, sinon une trace de pile est imprimée dans le journal de débogage et le JSON est annulé. Auquel cas cela ne fonctionne pas : https://code.samourai.io/wallet/samourai-wallet-android/-/blob/develop/app/src/main/java/com/samourai/wallet/api/APIFactory .java#L259

Il s’agit d’un problème très grave à grande échelle, c’est pourquoi je vous contacte d’abord pour vous informer en privé afin que le problème puisse être reproduit et résolu. Je pense qu’en imposant une exigence selon laquelle la valeur de l’index ne peut qu’augmenter et en la conservant dans le stockage, cela devrait aider à résoudre le problème.

À un niveau élevé, chaque portefeuille HD nécessite un index pour garder une trace de « où se trouve le portefeuille » dans le chemin de dérivation pour ce type d’adresse, c’est-à-dire quelle adresse a été utilisée en dernier et quelle adresse utiliser ensuite. Dans le cas du portefeuille Samourai, cela est fourni dans un objet JSON alimenté par le back-end. Cependant, j’ai découvert un manque de gestion des erreurs, où l’objet JSON peut être annulé (entraînant qu’aucun index ne soit défini, ce qui oblige le portefeuille à réutiliser les adresses à partir de l’index 0) dans toute situation où le client reçoit des données mal formées ou toute interruption de connexion réseau. se produit. Ce problème aurait pu être résolu grâce à des contrôles de sécurité locaux et à une gestion appropriée des erreurs, mais aucun n’était en place.

Au cours du dernier mois, j’ai fait trois demandes de mises à jour pour savoir si l’équipe Samourai avait été en mesure de reproduire le problème. Leurs réponses ont été courtes et ne m’ont donné aucune clarté sur l’avancée de leur enquête.​​​​​​​

Hier, ils ont publié leur propre déclaration, mais celle-ci ne faisait aucune mention ni réfutation du problème particulier que je leur avais explicitement signalé. C’est troublant ; comme vous vous en souviendrez peut-être, le manque de mécanismes de gestion des erreurs pour les demandes de données provenant de sources externes est similaire au défaut architectural de la dépendance de Blockchain.info (maintenant Blockchain.com) à random.org., provoquant un échec d’entropie qui a entraîné des clés privées des utilisateurs. être prévisible par n’importe qui.​​​​​​​ [https://www.reddit.com/r/Bitcoin/comments/aom95b/a_fun_little_memory_about_blockchaininfo/ | https://www.reddit.com/r/Bitcoin/comments/ch7nun/samouraileaks_part_3_is_randomorg_random_enough/].

Ce problème peut être dû à des problèmes de connectivité ou à des réponses invalides dues à une erreur dans le back-end, ce qui rend le client vulnérable non seulement à un back-end malveillant mais également à un intermédiaire réseau. (Pour être clair, je ne prétends pas que les développeurs de Samourai se lanceraient dans une telle attaque. Je souligne simplement qu’il est possible de déclencher intentionnellement ce comportement de cette manière. Cela est également vrai pour l’instance Dojo de quelqu’un d’autre.)

Au lieu de résoudre le problème directement, leur correctif consiste à effectuer un meilleur filtrage des transactions sur le back-end.​​​​​​​ Heureusement, cette fois, ce n’était pas quelque chose de suffisamment sensible pour mettre les fonds en danger. Mais étant donné la nature de Samourai Wallet en tant qu’outil de confidentialité, cela reste déconcertant. En fin de compte, chaque fois que le portefeuille est démarré, il démarre avec l’index par défaut de 0. À moins que le client ne parvienne à interroger avec succès l’index depuis le back-end, cette valeur par défaut sera utilisée pour construire de nouvelles transactions (cette valeur n’est pas conservée sur le portefeuille). appareil). Aucune erreur n’est affichée à l’utilisateur en cas d’échec de la requête. Le client acceptera également aveuglément tout ce qui lui est fourni par le back-end sans aucun doute.​​​​​ Des instances de cette réutilisation d’adresses sont observables sur la blockchain au-delà de ce que l’utilisateur qui m’a signalé cela a vécu.

D’après ce que je vois, Samourai a décidé de patcher le back-end avec de nouveaux critères de filtrage qui vérifient les transactions pour la réutilisation des adresses sur les serveurs du Dojo ou de Samourai avant leur diffusion. Cela pourrait potentiellement laisser de côté des cas marginaux, tels que les utilisateurs qui créent des transactions et diffusent par d’autres moyens. (Il est également important de mentionner que le client Whirlpool ne souffre pas de ce problème, car il conserve localement les valeurs d’index pertinentes.)

La dernière chose que je veux dire est un point général sur la façon dont les gens interagissent les uns avec les autres dans cet espace. Au cours des deux dernières années, l’équipe Samourai a consacré beaucoup de temps et de ressources à l’analyse des flux de pièces via son concurrent Wasabi. Ils leur reprochent un comportement post-mix consciemment adopté par les utilisateurs finaux (ce qui est impossible à empêcher dans un portefeuille non dépositaire). Pendant ce temps, leurs propres outils présentaient des cas de réutilisation d’adresses en raison de mécanismes d’architecture et de gestion des erreurs médiocres. Dire « jeter des pierres depuis une maison de verre » est, à mon avis, un euphémisme.

En raison de la manière dont ils s’engagent de manière combative dans de nombreux autres projets dans l’espace, je soupçonne qu’il y a moins d’yeux qui vérifient leur base de code à la recherche de problèmes qu’il n’y en aurait autrement. En fin de compte, ce sont les utilisateurs et non les concurrents qui souffrent le plus de la dynamique créée par cet environnement.

Il s’agit d’un petit sous-ensemble des transactions globales que j’ai envoyées aux développeurs Samourai (200 TX), dont certaines ont été vérifiées manuellement.

Il s’agit d’une liste des 5 113 scripts réutilisés dans les dépenses post-mix que j’ai pu identifier.

J’étudierai les différences entre le nombre d’adresses réutilisées dans mon analyse et celle de Samourai, je rechercherai d’éventuels faux positifs, et je ferai un suivi une fois terminé.

ADDENDA (16/07/2020): L’analyse de Samourai des faux positifs dans l’ensemble global de réutilisation d’adresses est correcte à 100 %. Après la communication initiale de l’utilisateur concerné qui m’a contacté, j’ai contacté Nothingmuch pour voir s’il pouvait m’aider à une analyse plus approfondie sans avoir à partager les TXID relatifs à l’utilisateur concerné et pour voir si le problème existait au-delà de la portée de cet utilisateur unique. L’ensemble de données Dumpling de Nopara a été utilisé pour analyser toutes les dépenses post-mix de Samourai pour les cas de réutilisation d’adresses, car il était facilement disponible (en remarque, il est important de considérer que seules les transactions post-mix ont été analysées pour la réutilisation, l’utilisateur initialement concerné étant amené à mon attention sur une transaction post-mix, c’est donc l’ensemble de transactions qui a été analysé). La raison de la disparité dans le nombre de réutilisations était l’incapacité de filtrer correctement les instances de « réutilisation » qui équivalaient à un script apparaissant une fois en sortie et étant dépensé une fois en entrée. Le décompte de Samourai de 441 adresses réutilisées est correct, pas le nombre 5113 auquel je suis arrivé.

Cependant, cela ne change pas la nature du bug dans le client, ni sa gravité pour les utilisateurs individuels concernés. Je suis toujours fermement convaincu qu’un correctif approprié consisterait à conserver localement les index de portefeuille pertinents de la même manière que le client de bureau Whirlpool. J’ai rendu tout cela public de manière transparente, avec toutes les données nécessaires pour vérifier à la fois la réutilisation en chaîne et le code relatif au bug, et j’ai décrit ci-dessus la cause de l’erreur constatée dans mes chiffres. Je n’ai pas l’intention de me lancer dans des bagarres ou des disputes sur les réseaux sociaux, tout ce qui est nécessaire pour vérifier ce problème se trouve ici, et ce que chaque individu choisit d’en faire est sa décision.

Share this content:

Laisser un commentaire