Bonjour tout le monde,
J’ai l’honneur de vous présenter une nouvelle bibliothèque Java (en fait compatible avec n’importe quel langage qui utilise la machine virtuelle Java, normalement) : confusable-homoglyphs. « Nouvelle » dans sa version Java, car c’est en réalité un portage d’une bibliothèque Python. Notez qu’il en existe aussi une version PHP.
C’est un outil sous licence Apache 2.0 qui permet de gérer directement au sein d’une application les caractères Unicode qui se ressemblent, et donc qui sont source de confusion.
Quel est donc le but de cette bibliothèque ?
Les humains utilisent divers systèmes d’écriture, et ce qui devait arriver, arriva : il y a des caractères qui se ressemblent (voire qui sont graphiquement identiques, selon la police d’écriture), mais qui sont différents. Or, de telles confusions peuvent avoir des conséquences fâcheuses, par exemple :
- l’utilisateur « ΑlaskaJazz » (le premier Α est un alpha majuscule grec) peut se faire passer pour l’utilisateur « AlaskaJazz » (uniquement des lettres latines) ;
- on peut vous inciter à vous connecter sur www.microsоft.com ou www.faϲebook.com au lieu de www.microsoft.com ou www.facebook.com ;
- etc., on pourrait multiplier les exemples désagréables à l’infini.
Si Unicode fournit des listes des caractères qui peuvent prêter à confusion, elles sont difficiles à utiliser en l’état : ce sont des fichiers textes avec un formatage particulier, qui plus est hébergés sur des serveurs instables et fréquemment hors ligne.
confusable-homoglyphs permet de gérer ces confusions en détectant et donnant des informations sur les caractères potentiellement problématiques.
D’accord, mais comment ça s’utilise ?
La bibliothèque est disponible sur Maven Central et donc s’importe comme n’importe quelle autre bibliothèque Java, ici avec Maven ou Gradle :
<dependency>
<groupId>fr.spacefox</groupId>
<artifactId>confusable-homoglyphs</artifactId>
<version>1.0.1</version>
</dependency>
compile group: 'fr.spacefox', name: 'confusable-homoglyphs', version: '1.0.1'
Puis on initialise l’une des deux classes utilitaires, selon ce qu’on veut faire :
Categories categories = Categories.fromInternal();
Confusables confusables = Confusables.fromInternal();
// ou si on préfère fournir un jeu de données spécifique :
Categories categories = Categories.fromJson("/full/path/to/categories.json");
Confusables confusables = fromJsons("/full/path/to/categories.json", "/full/path/to/confusables.json");
// (Confusables utilise Categories en interne).
Et on utilise les objets créés. Il y a un résumé de l’API publique ici. La création est relativement longue par rapport à l’utilisation, il vaut mieux garder ces objets vivants entre deux appels.
Les intentions et contraintes du projet
En réalité, je n’ai pas besoin de cette bibliothèque, au‐delà du fait que je trouve qu’elle manque à Java. Je voulais aussi et surtout :
- connaître la difficulté à porter une bibliothèque de Python à Java ;
- voir ce que c’est de créer un projet, seul, de A à Z et complet (avec documentation et tout) ;
- essayer de déployer quelque chose sur Maven (en tant que fournisseur).
Les contraintes que je me suis choisies pour ce projet étaient donc :
- licence libre (Apache 2.0) ;
- Java 8, pour garder une bonne compatibilité avec les projets actuels et les différents langages qui utilisent la machine virtuelle Java ;
- une API aussi proche de possible que l’originale (il y aura une version 2 avec des modifications dans cette API, un jour) ;
- disponible sur Maven Central, pour être utilisable comme n’importe quelle bibliothèque Java ;
- avec une doc complète ;
- avec une couverture de tests correcte ;
- avec de l’intégration continue via GitHub (j’ai toujours utilisé GitLab et GitLab CI pour mes autres projets Java).
Et comme j’aime bien partager mon expérience, j’ai écrit un billet sur ce que j’ai tiré de celle‐ci.
Je n’ai jamais eu l’occasion de vérifier que tout fonctionne bien sous Android. Si quelqu’un s’en sert dans cet environnement, que cette personne n’hésite pas à me faire signe. J’espère que ce petit utilitaire – ou les versions Python ou PHP – pourront vous servir un jour ! N’hésitez pas à créer tickets et demandes d’intégration (pull requests) si le cœur vous en dit !
Cette dépêche est publiée sous licence CC BY 4.0.
Aller plus loin
- Dépôt Git de confusables-homoglyphs (Java) (49 clics)
- Version Python (originale) de confusables_homoglyphs (57 clics)
- Portage en PHP de confusable-homoglyphs (47 clics)
- Retour d’expérience sur le portage Python → Java (36 clics)
# Microsоft.com, Faϲebook.com
Posté par HL . Évalué à 8. Dernière modification le 14 mars 2019 à 14:14.
La confusion tient beaucoup de la police de caractère :
Dans l'article de la dépêche il n'était pas possible de voir la différence (Firefox/W7).
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Ysabeau 🧶 (site web personnel, Mastodon) . Évalué à 10.
Certes, mais beaucoup de gens n'y font pas attention ! Voire, n'ont aucune idée de ce qui est possible de faire.
Le nombre de gens pourtant n'ayant jamais connu de machine à écrire qui écrivent des O majuscule à la place des zéros est assez consternant. Et ces personnes ne voient pas les différences qui, pourtant, sautent aux yeux (aux miens, en tout cas), alors pour des caractères « exotiques ».
Et, effectivement, dans le texte de la dépêche, les caractères sont visuellement identiques.
« Tak ne veut pas quʼon pense à lui, il veut quʼon pense », Terry Pratchett, Déraillé.
[^] # Re: Microsоft.com, Faϲebook.com
Posté par guppy . Évalué à 5.
C'est vrai qu'on voit ça souvent. A leur décharge, ces 2 caractères sont contigus sur le layout Azerty et s'obtiennent en pressant SHIFT. Un petit dérapage et c'est l'erreur. Je crois même que ça m'est déjà arrivé (bon j'ai corrigé parce que j'y suis sensible mais la plupart des gens n'y attache pas grande importance).
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Pierre Jarillon (site web personnel) . Évalué à 4.
C'est aussi vrai avec Firefox avec Mageia. C'est justement l'objet de cet article.
La confusion entre deux glyphes de même apparence est utilisée par des tas d'escrocs !
Ce serait bien que l'affichage des URL contenant des caractères non ascii soit systématiquement contrôlé et que les caractères hors ascii soient colorés d'une façon très perceptible.
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Jehan (site web personnel, Mastodon) . Évalué à 10.
Alors ça sûrement pas. C'est la pire des réponses au problème qui pourrait être faite. Et malheureusement c'est le genre de réponses qui est souvent faite par certains développeurs des pays occidentaux et ça explique probablement en partie le peu d'intérêt des logiciels libres dans pas mal de pays (en tous cas, dans les pays extrême-orientaux, je peux attester que le libre est très anecdotique par exemple). De nos jours, pas mal de trucs se sont vachement améliorés heureusement, mais par exemple pendant longtemps, les difficultés pour installer les méthodes d'entrée pour langue non européennes rendaient évident que des barrières étaient créées dès l'installation d'un OS libre.
Donc pour bien revenir au sujet, non pas tout le monde n'utilise les caractères latin (encore moins le sous-ensemble ASCII) et il n'y a aucune raison pour l'imposer au monde entier.
Ainsi si on prend les exemples:
Αlaska
est problématique, oui, mais parce que le reste des lettres est dans l'alphabet latin et surtout "Alaska" est un nom propre en anglais.Mais si maintenant le mot était
Αλάσκα
(qui apparemment veut dire Alaska en grec, cf. Wikipédia) alors leΑ
(alpha majuscule grec) est attendu et ce serait leA
ASCII qui serait problématique, et possiblement utilisé pour tromper autrui (pas forcément, notez bien, mais "possiblement").Ensuite on pourrait imaginer des cas où mélanger les alphabets/syllabaires peut être acceptables, que ce soit pour des jeux de mots ou du character art (beaucoup utilisent des scripts non locaux pour leur forme, j'en ai repéré sur linuxfr même, au fil des ans). Ou simplement on pourrait imaginer un franco-grec avec un prénom composé (un nom français, un grec, ça ne me paraît pas improbable), etc. Donc ce n'est pas forcément un problème simple à résoudre. Mais si on veut gérer ces problèmes, c'est par ce type de réflexion et pas en disant "tout en ASCII". On est dans un monde Unicode, et c'est une avancée, pas de retour en arrière SVP! :P
De mémoire, il me semble qu'il existe même plusieurs RFCs qui évoquent ce type de problèmes (notamment pour la problématique des noms de domaine acceptables), et ce sur de nombreuses pages (je peux assurer qu'aucune de ces RFC ne dira juste "utilisez tous ASCII", surtout en s'adressant à des pays dont la langue n'utilise pas les caractères latins!).
Sinon, et pour parler un peu de la librairie de l'article, en jetant un œil au README du dépôt, il semblerait que cette bibliothèque gère certains trucs intéressants. Déjà je vois les notions de mixed script, etc. J'ai pas cherché beaucoup plus loin, mais ça a l'air correct d'un rapide coup d'œil. :-)
Film d'animation libre en CC by-sa/Art Libre, fait avec GIMP et autre logiciels libres: ZeMarmot [ http://film.zemarmot.net ]
[^] # Re: Microsоft.com, Faϲebook.com
Posté par fearan . Évalué à 1.
Je sais pas, sans vouloir être pour la domination d'une langue en particulier, lire du code dans un alphabet utf-8, peut s'avérer ardu, surtout si le jeu de caractère n'est pas présent/dispo sur la machine.
L'alphabet latin est connu d'à peu près tout le monde (les japonais l’apprennent, même s'il n'est pas le leur), il à l'intérêt de ne pas avoir de collision ou peu (i, 1 I l |, qui sont facilement visible avec les polices de codage)
Pour les url, je serai pour avoir un indicateur visuel dès que des caractères sortent du groupement majoritaire, et un indicateur différent selon l'origine du caractère, on a je ne sais combien de a en utf-8, mais cela ne s'arrête pas la, on peut jouer avec les . les / et autre éléments constitutifs des url.
D'un point de vue purement codage, sémantique et autre, se limiter a 255 caractère simplifie beaucoup l'écriture des lexeurs et on à moins de cas particulier à gérer (et encore, si on se limite à l'ascii commun (sans accent)), on simplifie encore plus, un nom de fonction/variable c'est [a-zA-Z0-9_]+; si on se met à gérer tous les alphabet existant, on doit gérer les espaces (quadratin, insécable, autre), les barres obliques, séparateurs, mais bon c'est mon coté flémouille qui s'y colle…
Le soucis c'est qu'en jouant assez bien on doit très facilement pouvoir ajouter des backdoor rien, qu'en trichant sur les héritages ou affectation de variable à la graphie similaire.
Ensuite on pourrait limiter les fichiers de code à un ensemble de caractère correspondant à une langue; pour les url colorier les caractères des url en fonction des risque des confusion (latin, hiragana, katakana => bleu; arabe, grec => vert…)
nan utf-8 et c'est la chianli, impossible de savoir facilement combien d'octet fait ta chaine de 15 caractères, la différence de perf entre un LANG=C grep et grep tout court est assez impressionnante; on devrait utiliser du utf-16 ou utf-32; où les caractères sont de taille fixe.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Microsоft.com, Faϲebook.com
Posté par lolop (site web personnel) . Évalué à 2.
UTF8 c'est un format de stockage relativement optimal mais qui complique les traitements. Rien ne t'empêche de passer vers un format plus pratique lorsque tu manipules des chaînes dans ton programme, certains langages le font.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: Microsоft.com, Faϲebook.com
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 19 mars 2019 à 21:56.
J'ai déjà répondu au gros du message plus bas, avant que tu ne le postes. Je trouves ça triste de vouloir restreindre l'incroyable richesse des langues mondiales, et de vouloir imposer un système d'écriture qui n'est pas celui de l'incroyable majorité de la population mondiale (pas même du français, à cause des diacritiques).
Cela dit :
Les caractères UTF-16 n'ont pas une taille fixe (même si ce n'est pas la même gestion qu'avec UTF-8).
PS : tu mélanges un peu tout. Unicode a prévu des classes de caractères. Pour la programmation, il suffit de n'accepter comme identifiants que ce qui est un caractère réel, pas un symbole ou une espace etc.
La connaissance libre : https://zestedesavoir.com
[^] # Re: Microsоft.com, Faϲebook.com
Posté par fearan . Évalué à 2.
Yep, c'est triste d'avoir un langage qui impose des mots clés ascii, et anglais qui plus est, mais y a tellement de moyen de tricher avec l'utf-8…
yep, puisque tu parles de python
facile à tester et c'est marrant on a pas 2 fois la même ligne! Ça l'est moins si c'est un uid, ou un élément critique du système
Note bien j'ai proposé une solution simple : n'accepter qu'un jeu restreint de caractères par fichier, afin d'éviter ce genre de blague, mais ça devient galère lorsque les mots clés du langage sont dans un alphabet proche.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Anonyme . Évalué à 1.
C’est marrant, c’est typiquement le genre de problème que tu ne rencontre pas dans la vrai vie.
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 3.
Le Japon est un mauvais example. Ils sont très attirés par l'anglais (même s'ils ne le parlent pas bien), au point d'avoir de l'anglais dans un nombre impressionant de shows/quiz à la télé, et que les écoles de langues pullullent. N'oublions pas que les USA se sont aussi imposés physiquement au Japon après la seconde guerre.
Je serais plus interessé de qu'on parle de langues de pays ou l'anglais est moins bien vu et/ou moins présent.
[^] # Re: Microsоft.com, Faϲebook.com
Posté par fearan . Évalué à 2.
Le soucis c'est que les langages de programmations sont intrinsèquement anglais (dans leur immense majorité) (class, interface, private, struct, if, for, while, overide, implements, int, float, long, Integer, import, include, iterator, map…) et nécessite donc des bases de l'alphabet latin; qu'un langage d'origine coréenne refuse les caractères latins comme identifiants des variables/fonctions ne me choquerait pas
mixer 2 alphabets pour coder ça risque d'être marrant, surtout si les sens de lecture sont différents)
y'a déjà eu ce genre de question posé, et il existe notamment un langage arabophone:
https://www.developpez.com/actu/51298/Un-scientifique-sort-un-nouveau-langage-de-programmation-en-arabe-pour-demystifier-l-art-de-coder/
A supposer qu'on puisse coder dans un autre alphabet, en gardant les mots clé latin, soit, mais cela n'a aucun sens de mixer 2 alphabets pour les identifiants, et devrait, à minima, donner un warning.
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Axioplase ıɥs∀ (site web personnel) . Évalué à 3.
Je pensais aux URLs, pas au code…
Et j'ai vu suffisamment de code avec des variables en japonais :)
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Anonyme . Évalué à 1.
Il n’y a pas de lien évident entre l’hameçonnage et les IDN.
[^] # Re: Microsоft.com, Faϲebook.com
Posté par HL . Évalué à -2.
Il y a eu quelques cas sur Whatsapp par exemple.
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Anonyme . Évalué à 2.
L’exemple donné est tellement évident que l’attaquant aurait pu mettre
login.paypal.pas-du-tout-du-phishing.example
, ça n’aurait rien changé.Et puis quelle différence entre ça et un mail en HTML avec un lien du style :
[login.paypal.com](login.paypal.phishing.example)
?[^] # Re: Microsоft.com, Faϲebook.com
Posté par HL . Évalué à 1.
Mon précédent message n'était en rien une prise de position. J'ai simplement déjà vu des tentatives (un autre exemple jouait sur sur une lettre semblable du l de lidl.com)
En ce qui concerne la remarque suivante:
Un lien de ce style est plus facilement détectable puisque l'url sur lequel on se connecte n'est pas un homographe (on s'en rend compte en passant la souris dessus, en regardant la barre d'adresse, etc.). C'est plus difficile avec Ιidl.com (la première lettre est un iota majuscule ; ça se voit mieux avec le formatage "code" :
Ιidl.com
, du moins sur la machine que j'utilise).[^] # Re: Microsоft.com, Faϲebook.com
Posté par dinomasque . Évalué à 1.
C'est un article qui date de 2009 : en 10 ans tout a eu le temps de tellement évoluer.
BeOS le faisait il y a 20 ans !
[^] # Re: Microsоft.com, Faϲebook.com
Posté par Thierry Thomas (site web personnel, Mastodon) . Évalué à 3.
Sans parler d’escrocs, j’ai rencontré récemment un problème sur l’importation d’un simple fichier CSV suite à la confusion entre un × (multiplication) et un x (X minuscule).
# Quelques précisions…
Posté par SpaceFox (site web personnel, Mastodon) . Évalué à 8. Dernière modification le 15 mars 2019 à 17:24.
Hello,
Déjà l'honnêteté intellectuelle m'oblige à préciser qu'en réalité,tant qu'on parle de la JVM ICU permet déjà ce genre de chose (en plus complet mais avec une API plus compliquée, et sans garantie quant à la gestion des catégories, cf ci-dessous).
Et quelques précisions pour répondre aux commentaires ci-dessus.
Je précise que l'outil fait de la détection multi-caractères :
©
et(c)
vont être considérés comme pouvant être confondus (dans les deux sens).Bien évidemment, ce genre d'outil ne doit servir en aucun cas à forcer du simple ASCII. Unicode est un progrès gigantesque dans un monde où les outils de l'état massacrent encore les noms et prénoms de ses propres citoyens (ceux qui ont une diacritique dans leur nom ou prénom savent à quel point elle est souvent supprimée). Ne nous servons pas de ces possibilités pour régresser, merci.
C'est pour ça qu'il y a des outils pour récupérer des alias et surtout des catégories sur les caractères ; et surtout que les outils de gestion des confusions permettent de gérer des catégories de caractères « de base ». Par exemple pour une application en Français, on voudrait d'autoriser / ne détecter les risques de confusion qu'au sein d'une classe de caractères. Par exemple, une application en français voudrait pouvoir éviter les chaines qui contiennent des caractères que l'on peut confondre avec des caractères latins mais qui n'en sont pas (les caractères latins sont considérés comme légitimes). Une application en russe voudrait elle que ce soit les caractères cyrilliques qui sont légitimes. Je vous renvoie à la doc pour plus de détails1
Aujourd'hui ce qu'il manque à confusables-homoglyphs, c'est l'équivalent des skeleton de ICU, c'est-à-dire une fonctionnalité qui permet d'enregistrer une version « normalisée » d'une chaine de caractères. Cette version n'est pas utilisable à l'affichage, mais permet des comparaisons : deux chaines de même squelette peuvent être confondues. En enregistrant le squelette dans un champ ad hoc, on peut autoriser par exemple des pseudonymes avec n'importe quels caractères, tout en interdisant facilement tout autre pseudonyme homoglyphe.
Enfin, tout l'intérêt des exemples était de montrer que dans certains cas, il n'y a absolument aucun moyen graphique de discerner deux homoglyphes. En réalité l'exemple des noms de domaines était repiqué de la doc d'origine, mais est assez mauvais parce que les navigateurs vont afficher le nom de domaine canonique, donc http://www.xn--faebook-6pf.com/ et http://www.xn--microsft-sbh.com/ – en plus du fait que les utilisateurs font rarement attention à ce qu'il y a dans la barre d'URL.
Celle du projet Python d'origine, j'ai oublié de publier la doc Java… ↩
La connaissance libre : https://zestedesavoir.com
# Commentaire supprimé
Posté par Karine.zabolski . Évalué à -1. Dernière modification le 17 mars 2019 à 14:08.
Ce commentaire a été supprimé par l’équipe de modération.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.