Recherche par nom de Profil sécurisée (y compris pour les non-membre)

Proposition pour une recherche de profils par nom plus sûre

Dans le cadre du projet Dunipod, j’ai développé une manière d’indexer les noms de profils qui atténue les risques d’usurpation de nom.

Un problème présent depuis toujours dans la Ğ1 est que n’importe qui peut créer un profil avec le même nom et le même avatar que vous afin de se faire passer pour vous et de recevoir à votre place certaines transactions qui vous sont destinées.

C’est pourquoi il est recommandé d’utiliser un QR code ou de recopier l’adresse (anciennement la clé publique) de la personne que l’on souhaite payer.

Pour autant, la recherche par nom reste utile lorsque l’on ne dispose ni du QR code ni de l’adresse d’une personne et que l’on ne sait pas comment la contacter autrement.

Ce problème me travaille depuis des années, mais j’étais concentré sur Duniter et j’espérais que d’autres feraient émerger une solution satisfaisante. Comme ce n’est toujours pas le cas, j’ai décidé de proposer ma propre solution.

Il ne s’agit pas d’une solution purement théorique : je l’ai testée sur les quelque 60 000 profils Ğ1 existants et je l’ai affinée au fur et à mesure de mes essais. Ce que je vais décrire ci-dessous n’est toutefois pas gravé dans le marbre. C’est une proposition qui sera affinée en fonction des retours constructifs et de nos futurs tests.

J’ai fait une interface web (dépôt gitlab) qui utilise mon pod Dunipod afin de vous permettre de tester ma solution de recherche de profils par nom (elle est encore lente, optimisations à venir):

Résumé de la solution

Tous les profils sont regroupés en fonction de la similarité de leur nom.

Si un groupe ne contient qu’un seul profil, celui-ci est classé comme légitime.

Si un groupe contient plusieurs profils :

  • soit l’un d’eux peut être objectivement considéré comme plus légitime que les autres : il est alors classé comme légitime et les autres comme suspects ;
  • soit aucun d’eux ne peut être départagé : ils sont alors tous classés comme ambigus.

L’ordre des résultats d’une recherche par nom est le suivant :

  1. Les profils de membres légitimes
  2. Les profils de non-membres légitimes
  3. Les profils de membres ambigus
  4. Les profils de non-membres ambigus
  5. Les profils de membres suspects
  6. Les profils de non-membres suspects

Les profils suspects (catégories 5 et 6) sont masqués par défaut. Un paramètre GraphQL (includeSuspicious: Boolean) permet de les inclure dans les résultats.

Pour départager plusieurs profils dont les noms sont similaires, les critères suivants sont pris en compte :

  • le rattachement éventuel du profil à une identité membre ;
  • le bloc d’ancrage on-chain du profil (voir la section « Établir un ordre grâce à un ancrage dans la blockchain ») ;
  • le statut « signalé » du profil (voir la section « Ajouter une modération communautaire »).

Les règles complètes de classement et les différents cas limites sont détaillés dans la documentation sur l’indexation des profils et dans celle consacrée à l’ancrage des noms de profils.

Détecter les noms qui peuvent être confondus

La première étape consiste à ne pas comparer uniquement les noms tels qu’ils sont écrits.

Dunipod transforme chaque nom en une forme destinée à la comparaison. Les différences de majuscules, d’espaces, de ponctuation ou d’accents sont ainsi neutralisées. Certains caractères provenant d’alphabets différents mais ayant une apparence proche sont également considérés comme équivalents.

Par exemple, une recherche sur Elois peut retrouver Eloïs, et une recherche sur Eloi peut également proposer Éloïse.

Dunipod détecte aussi les petites fautes de frappe : une lettre ajoutée, supprimée, remplacée ou l’inversion de deux lettres. Ainsi, créer un profil dont le nom diffère seulement d’un caractère ne suffit pas à contourner la détection.

L’objectif n’est pas de déterminer si deux noms désignent réellement la même personne. Il est simplement de repérer les noms suffisamment proches pour qu’un utilisateur puisse raisonnablement les confondre.

Ne pas rendre les noms uniques

Je ne propose pas de rendre chaque nom unique. Plusieurs personnes peuvent légitimement porter le même nom, et réserver définitivement un nom au premier profil reçu par un pod poserait d’autres problèmes.

Les pods d’un réseau décentralisé ne reçoivent pas nécessairement les documents dans le même ordre. Un attaquant pourrait également publier très rapidement une copie d’un nouveau profil afin de rendre le profil légitime suspect. L’ordre d’arrivée sur un pod ne constitue donc pas une preuve fiable.

Lorsqu’il existe plusieurs profils aux noms similaires et qu’aucun élément objectif ne permet de les départager, Dunipod les classe comme ambigus et les laisse tous visibles dans la recherche. L’application peut alors avertir l’utilisateur et lui présenter les informations permettant de les distinguer : adresse, statut de membre, description, ville, liens sociaux, ancienneté du profil, etc.

Masquer arbitrairement l’un de ces profils créerait un moyen très simple de censurer une personne en copiant son nom.

Donner la priorité aux profils liés à une identité membre

Un profil peut être lié à une identité membre de la toile de confiance lorsque son signataire contrôle bien un compte associé à cette identité.

Dans ce cas, un profil créé par un non-membre avec un nom similaire ne peut ni rendre le profil du membre suspect ni le faire disparaître de la recherche. Cela empêche notamment un attaquant de créer de nombreux profils anonymes pour noyer le profil d’un membre.

Un profil de non-membre reste néanmoins accessible. Être membre ne constitue pas une preuve que l’on est la seule personne à pouvoir porter un nom, mais c’est une information utile pour ordonner les résultats.

Une même identité membre peut avoir plusieurs anciens profils ou plusieurs comptes associés. Dunipod n’en conserve qu’un seul comme profil courant dans la recherche par nom. Les autres restent consultables directement, mais ne viennent pas créer artificiellement des conflits.

Si deux membres distincts utilisent des noms similaires, aucun des deux n’obtient automatiquement la propriété du nom. Il faut alors un autre élément pour les départager.

Établir un ordre grâce à un ancrage dans la blockchain

Pour éviter qu’un attaquant puisse copier un profil immédiatement après sa publication, Dunipod propose un mécanisme d’ancrage facultatif.

Lorsqu’une application demande cet ancrage, le profil signé n’est pas immédiatement rendu public. Un relais inscrit d’abord dans un bloc Duniter un engagement cryptographique correspondant au profil. Plusieurs profils peuvent être regroupés dans un même ancrage afin d’éviter une transaction individuelle pour chacun d’eux.

Le contenu du profil reste stocké hors chaîne : seule une empreinte permettant de prouver son ancrage est inscrite dans la blockchain. Une fois le bloc finalisé, le profil peut être publié et partagé entre les pods avec son certificat d’ancrage.

Si deux profils ont des noms trop proches, celui qui possède l’ancrage finalisé le plus ancien est présenté normalement. Le profil ancré plus tard est classé comme suspect et masqué par défaut dans la recherche courante. Il reste néanmoins possible de l’afficher explicitement à des fins de vérification.

Si aucun des deux profils n’est ancré, ou si les deux ont été ancrés dans le même bloc, Dunipod ne prétend pas connaître leur ordre de publication : ils restent ambigus et visibles.

L’ancrage ne certifie pas l’identité réelle d’une personne. Il apporte seulement une preuve objective d’antériorité entre plusieurs profils similaires.

Dans le MVP actuel, l’application choisit un relais d’ancrage auquel elle fait confiance pour ne pas divulguer prématurément le profil et pour transmettre effectivement l’ancrage. Le relais ne peut pas modifier le profil, car celui-ci est signé par son propriétaire.

Présenter les résultats dans un ordre utile

La recherche classe les résultats en plusieurs groupes :

  • les profils considérés comme légitimes ;
  • les profils ambigus, lorsqu’un conflit existe sans qu’il soit possible de désigner objectivement un profil prioritaire ;
  • les profils suspects, qui sont masqués par défaut mais peuvent être affichés à la demande.

À l’intérieur du premier groupe, les profils liés à une identité membre sont présentés avant les profils non membres. La pertinence de la recherche intervient ensuite : correspondance exacte, variante avec accents, préfixe ou petite faute de frappe.

Ainsi, une personne qui recherche un nom voit d’abord les résultats les plus plausibles, sans que les cas ambigus soient arbitrairement supprimés.

Avertir avant la publication d’un profil

Dunipod permet également à une application de vérifier un nom avant de publier un profil.

L’application peut demander si ce nom est déjà utilisé ou s’il ressemble trop à des noms existants. En cas de conflit, elle peut afficher les profils concernés et avertir la personne avant qu’elle ne confirme son choix.

Cela permet d’éviter les collisions accidentelles et de rendre plus visible une tentative d’imitation. Le serveur n’interdit pas nécessairement la publication : c’est à l’application de présenter clairement le risque et, éventuellement, de demander un autre nom.

Modération communautaire

Le MVP permet enfin de publier des signalements ou, au contraire, des avis favorables concernant un profil. Ces avis sont eux-mêmes signés et restent publics.

Les avis provenant de membres sont comptés une seule fois par identité membre, même si celle-ci contrôle plusieurs comptes. Ils ont davantage de poids que les signalements provenant de comptes non membres. Par exemple, l’avis favorable d’un membre protège un profil contre un ensemble de signalements provenant uniquement de non-membres.

Ce mécanisme ne sert pas à attribuer la propriété d’un nom. Il complète la détection automatique pour traiter les cas manifestement abusifs. Lorsqu’un profil signalé entre en conflit avec un autre profil au nom similaire, il ne peut plus utiliser son ancienneté pour écarter l’autre résultat.

Ce que cette proposition ne résout pas

Cette méthode réduit les risques d’usurpation lors d’une recherche par nom, mais elle ne transforme pas un nom de profil en identifiant fiable.

Un nom, un avatar, une description et même des liens sociaux peuvent être copiés. L’ancrage prouve une antériorité, pas une identité civile. L’appartenance à la toile de confiance fournit une information supplémentaire, mais deux membres peuvent légitimement porter le même nom.

Pour un paiement important, la bonne pratique reste donc de vérifier l’adresse du destinataire par un autre canal ou d’utiliser son QR code.

L’objectif est plus modeste : rendre la recherche par nom nettement moins dangereuse, signaler clairement les ambiguïtés et compliquer les usurpations opportunistes, sans instaurer une autorité centrale chargée d’attribuer les noms.

Cette proposition correspond à l’implémentation actuelle du MVP de Dunipod. Je suis intéressé par vos retours, notamment sur les cas concrets où ce classement produirait un résultat trompeur ou injuste. Si vous connaissez des profils existants qui constituent de bons cas limites, je pourrai les utiliser pour poursuivre les tests et affiner les règles.

Les règles complètes de classement et les différents cas limites sont détaillés dans la documentation sur l’indexation des profils et dans celle consacrée à l’ancrage des noms de profils.


J’ai fait une interface web (dépôt gitlab) qui utilise mon pod Dunipod afin de vous permettre de tester ma solution de recherche de profils par nom (elle est encore lente, optimisations à venir):

Je ne trouve pas mon identité membre. Les autres mentionnées sont des tests.

Ce qui pourrait être bien est d’afficher les adresses ss58 dans les résultats, peut-être leur forme succinte avec bien sûr la fin qui fait office de vérification.

Il pourrait y avoir une adresse aussi pour les profils gchange clairement affichée, pour éviter les escrocs, ou alors associer obligatoirement tout profil gchange à un compte portefeuille et/ou membre?

C’est parce que ton identité membre n’a pas de profil lié avec le nom « hypericum ». Je ne prends pas en compte les noms « on-chain », car pour moi c’est un mauvais choix d’avoir des noms on-chain; on a fait ça historiquement à défaut d’avoir une bonne solution off-chain.

Pour que ton profil membre apparaisse dans la recherche, il faut que tu donnes le nom « hypericum » à ton profil. Ce que tu peux faire depuis Cesium et peut-être d’autres apps ; je sais que Gecko ne le permet pas.

Donc il faudra très fortement conseiller à la définition du pseudo après l’invitation de mettre un nom de profil identique au pseudo, ou le faire automatiquement par défaut

Il n’y aura pas besoin. Si Dunipod finit par être adopté, soit j’aurai ajouté la gestion des noms on-chain, soit les apps auront basculé sur le fait de ne plus utiliser le nom on-chain et n’afficheront que le nom du profil lié. Et si cette direction est prise, je retirerai entièrement le nom on-chain de Duniter.