Avant un changement de poste, la mise en ligne d’un site ou le réflexe « j’ajoute juste un point d’exclamation » à un vieux mot de passe, beaucoup de gens cherchent si cette chaîne a déjà fuité. Les résultats pour « testeur de force », « Have I Been Pwned » et « vérificateur de fuite en ligne » se côtoient et semblent répondre à la même phrase. Ouvrez les pages : les protocoles se séparent. Certaines POSTENT le champ vers leur propre hôte. D’autres demandent à un tiers une liste de suffixes de hachage. D’autres encore téléchargent un lexique public de mots faibles et comparent dans l’onglet. Ces trois flux donnent trois réponses différentes à « le mot de passe a-t-il quitté cette page ».
Ce texte ne refait pas une jauge Faible / Moyen / Fort, et il n’apprend pas à attaquer la base d’autrui. La question est plus étroite : ce qu’une liste locale de fuites peut prouver, et ce qu’une requête « tout le web » peut prouver, si elle est faite honnêtement. Le contrôle de force de MyPassGen est du premier type : le candidat n’est pas envoyé ; la page compare une liste publique de mots faibles chargée avec le site ; chaque outil s’ouvre sans compte. Le reste de l’article pose la frontière, puis montre comment la confirmer dans l’onglet Réseau des outils de développement.
Trois « contrôles de mot de passe » qui n’ont rien à voir
Nommez d’abord les protocoles. Un texte marketing peut écrire « local », « jamais envoyé » et « vérifié contre les fuites » dans la même phrase, tout en désignant trois architectures.
| Méthode | Ce qui quitte le navigateur | Question à laquelle elle peut répondre |
|---|---|---|
| Remettre le mot de passe à un site | Le clair, ou un champ de formulaire réversible | L’hôte d’en face dit avoir « vérifié » — vous ne voyez pas la preuve |
| Requête de plage en k-anonymat (HIBP) | Les 5 premiers caractères hexadécimaux d’un hachage SHA-1 ou NTLM | Si ce hachage figure dans le corpus qu’ils tiennent |
| Comparaison locale à une liste publique de mots faibles | Un fichier de lexique statique, pas votre saisie | S’il s’agit d’une chaîne trop utilisée, du type 123456 ou password |
La première méthode est la plus simple à utiliser et la plus difficile à auditer. Une page peut promettre de « supprimer la requête tout de suite ». Journaux, sauvegardes et scripts d’analytics peuvent encore en garder une copie. La deuxième est le modèle que Have I Been Pwned documente pour Pwned Passwords : le navigateur hache d’abord, n’envoie que le préfixe à api.pwnedpasswords.com/range/{prefix}, puis compare les suffixes en local. La troisième n’envoie même pas de préfixe. Le lexique est un ensemble public de mots faibles courants — souvent quelques centaines à dix mille lignes, pas « chaque fuite d’Internet ».
Le National Institute of Standards and Technology américain, dans NIST SP 800-63B-4, demande aux vérificateurs de confronter un mot de passe nouveau ou changé à une liste de valeurs « courantes, prévisibles ou déjà compromises », et de ne pas empiler par-dessus des règles obligatoires majuscule / minuscule / chiffre / symbole. Il précise aussi que le rôle principal de cette liste noire est de bloquer les essais qu’un attaquant en ligne tente en premier ; une fois la liste plus large que la fenêtre de limitation de débit, les lignes supplémentaires rapportent peu. C’est exactement la place d’une liste locale « top N » : un premier tamis contre les mots faibles courants, pas une recherche dans chaque fichier de fuite.
Choisissez la question avant l’outil
« Un dictionnaire essaierait-il ceci en premier ? » et « cette chaîne figure-t-elle dans une fuite précise ? » sont deux phrases. Une liste locale répond à la première. Une requête de plage sur un corpus entier ne répond à la seconde que pour le corpus que l’autre partie détient vraiment. Ni l’une ni l’autre ne remplace la règle : ne réutilisez pas le même mot de passe d’un site à l’autre.
Ce que signifie remettre le clair à un site
Un certain nombre de « testeurs de mot de passe en ligne » mettent encore la chaîne du champ dans le corps de la requête. Certains nomment le champ JSON password. D’autres le glissent dans la query. D’autres appliquent un encodage réversible et POSTENT le résultat. Pour le navigateur, le trafic ressemble à un formulaire de connexion : l’hôte distant, le reverse proxy et le journal d’accès voient tous cette soumission.
HTTPS n’arrête que les oreilles sur le chemin. Il n’empêche pas l’autre bout d’écrire le clair sur disque, ni un script d’analytics de renvoyer le champ. Ce que vous cherchez à réduire, c’est si ce seul contrôle a créé un nouvel informé qui connaît désormais la chaîne. Ce n’est pas le métier de HTTPS. L’article précédent, comment vérifier que le chiffrement dans le navigateur n’envoie pas le texte clair, pose la même règle : un slogan ne prouve rien ; le trafic, si.
Il existe une façon plus discrète de le remettre : coller le candidat dans un paramètre de query, puis transférer l’URL à un collègue ou la jeter dans un ticket. Les chaînes de query atterrissent dans la ligne de requête et dans le journal distant. Certaines ressources tierces reçoivent encore le chemin et la query dans le Referer. Si la chaîne est un mot de passe de compte vivant, cette étape, c’est vous qui le diffusez. La valeur par défaut sûre : un vrai mot de passe reste dans le champ de l’onglet courant. Ne l’écrivez pas dans une URL, et ne le collez pas dans un « vérificateur » qui envoie l’original.
Une requête de corpus entier qui n’envoie qu’un préfixe
L’API de plage de Have I Been Pwned sépare « chercher dans un grand corpus » et « remettre l’original ». Les étapes documentées : encoder le mot de passe en UTF-8, calculer SHA-1 (NTLM est aussi proposé), prendre les cinq premiers caractères hexadécimaux, puis demander GET https://api.pwnedpasswords.com/range/{prefix}. La réponse est une liste de suffixes et de comptes d’occurrences, séparés par deux-points. Le client recoud préfixe et suffixe sur l’appareil et cherche une correspondance complète. Troy Hunt décrit ce modèle comme du k-anonymat dans Understanding Have I Been Pwned's Use of SHA-1 and k-Anonymity : le serveur voit un seau de hachages, pas le hachage entier, et pas le mot de passe.
Quand Cloudflare a publié le dispositif avec HIBP, il a donné des chiffres encore vérifiables dans l’article : avec un préfixe de 5 caractères, le seau médian contenait environ 305 hachages, et la réponse médiane pesait environ 12,2 Ko. L’API propose aussi Add-Padding: true, qui remplit chaque réponse d’environ 800 à 1 000 lignes, pour qu’un observateur ne puisse pas déduire « c’était un mot très courant » à la seule longueur. Tout cela rend une requête de plage bien plus retenue qu’un POST de clair — et c’est encore une requête sortante. Réseau montrera un appel à api.pwnedpasswords.com. Coupez le réseau : ce type de recherche doit échouer.
Une requête de plage n’est pas non plus « l’anonymat parfait ». Le préfixe dit à un observateur dans lequel des 165 seaux votre hachage est tombé. Si le script de la page copie l’original avant d’envoyer le préfixe, le k-anonymat n’y peut rien. La recherche d’e-mail et celle de mot de passe ne sont pas la même API : HIBP v3 utilise un préfixe de 6 caractères pour les plages d’e-mails hachés, et c’est une autre surface produit. Cet article ne compare que « ce mot de passe figure-t-il dans un corpus de mots de passe ». Il ne traite pas les abonnements de boîte ni la surveillance de domaine comme le même contrôle.
Donc « nous utilisons HIBP » n’est pas la même phrase que « le mot de passe n’a jamais quitté l’appareil ». La version exacte : l’original et le hachage complet ne partent pas, par conception ; un préfixe et une requête de plage, si. Si vous acceptez « un tiers qui tient le corpus apprend le seau de hachage », c’est un compromis d’ingénierie raisonnable. Si vous exigez « ce contrôle ne doit même pas envoyer un préfixe », utilisez la liste locale de la section suivante, et acceptez une couverture bien plus étroite.
Une liste locale ne charge qu’un lexique
Une comparaison locale inverse le flux : télécharger une liste publique de mots faibles vers l’origine courante, puis faire une recherche d’ensemble dans le script. Réseau peut montrer le lexique. Il ne doit pas montrer le candidat du champ. La liste elle-même est une donnée publique. Une source typique est un fichier « top N sur dix millions de mots de passe » dans SecLists, autour de la collection OWASP / Daniel Miessler. Elle répond à « le premier dictionnaire d’un attaquant essaierait-il ceci », pas à « ceci dort-il dans une fuite non publiée ».
Le contrôle de force de MyPassGen suit cette frontière. Après l’ouverture, la page demande data/leaked-top10k.txt : environ 860 lignes, un mot de passe en minuscules par ligne, qui commence par des chaînes du type 123456, password et qwerty. La comparaison a lieu dans le navigateur : minuscules d’abord, puis un petit jeu de variantes — traiter @ / 4 comme a, 0 comme o, et d’autres leets courants, plus retirer un à trois chiffres en fin — puis tester l’ensemble. Une correspondance est marquée Faible même si la chaîne « a l’air longue ». Si le lexique ne charge pas, le script retombe sur un tout petit jeu intégré (password, 123456 et quelques autres). Il ne bascule pas vers une API de fuites externe.
La barre de force est un second calcul local. Le bassin de caractères ajoute 26 + 26 + 10 + 32 selon la présence de minuscules, majuscules, chiffres et symboles. L’entropie vaut à peu près la longueur fois log2(bassin), puis une décote si trop de caractères se répètent. Les seuils : en dessous d’environ 40 bits Faible, 60 Moyen, 80 Fort, et 80 et plus Très fort. Moins de 8 caractères déclenche un avis « trop court » à part. Le générateur aléatoire accepte 6 à 128 caractères et part de 16. La force brute hors ligne est estimée à 1010 essais par seconde ; la limitation en ligne à 103 — des ordres de grandeur à lire, pas une promesse sur un GPU particulier. Les événements d’analytics enregistrent la note et si la liste a matché. Ils n’envoient pas le mot de passe.
Vous pouvez vérifier ces chiffres sur cette machine : comptez les lignes du lexique dans un éditeur ou avec wc -l. Réseau doit montrer le lexique et ne doit pas montrer la saisie. Cela ne s’écrit toujours pas « nous avons cherché sur tout le web ». Environ 860 lignes ne couvrent même pas le Top 10 000 public de SecLists, encore moins un corpus indexé par hachage de la taille de celui de HIBP. La seule conclusion honnête d’un échec : ce n’est pas un mot faible courant de cette liste.
Un échec n’est pas « sûr » et n’est pas « jamais fuité »
Une liste locale bloque le front d’un dictionnaire. Votre mot de passe peut encore figurer dans une fuite hors liste, dans un combo de credential stuffing, ou dans des essais ciblés sur votre site. Quand il en faut un nouveau, générez-le sur cet appareil. Ne gardez pas le vieux mot en y collant une année ou un point d’exclamation.
Une barre de force ne prouve pas l’absence de fuite
Une barre de force estime un espace de recherche. Elle ne fouille pas une archive. Un mot aléatoire de 20 caractères peut avoir une entropie élevée et déjà exister dans le fichier de fuite de quelqu’un d’autre. Les attaquants ne parcourront pas le jeu de caractères depuis le début ; ils essaieront la liste toute faite. À l’inverse, Password1! satisfait souvent un formulaire « doit contenir majuscule, minuscule, chiffre, symbole » et atterrit presque toujours sur une liste publique de mots faibles. C’est ce schéma de contournement qui a poussé le NIST à abandonner les règles de composition.
Si une page affiche à la fois une note de force et un résultat de liste, la liste doit primer sur la barre : une correspondance est Faible. La barre reste utile. Elle signale « trop court », « une seule classe de caractères », ou une suite clavier qwerty. Elle ne peut pas, à elle seule, délivrer un certificat « continuez à l’utiliser ». La décision dont vous avez besoin tient en deux phrases : trouvé dans la liste, ou moins de 8 caractères — changez tout de suite ; absent de la liste et assez long — ne le réutilisez quand même pas d’un site à l’autre, et écrivez une chaîne neuve pour les comptes importants avec un gestionnaire ou le générateur local.
« Une requête tout le web a dit qu’il n’y avait pas de match » n’est pas non plus la fin. Une requête de plage dépend de ce que l’autre corpus a ingéré et de son rythme de mise à jour. Les fuites non publiées, les mots de systèmes internes et les variantes pas encore hachées dans cet ensemble n’apparaîtront pas. C’est bien plus large qu’une liste locale de 860 lignes, et c’est encore l’échantillon de quelqu’un d’autre. Utiliser les deux outils va, si vous savez ce que chacun a envoyé et ce qu’un échec veut dire.
Vérifier dans Réseau : le lexique peut apparaître, le mot de passe non
Les étapes ci-dessous ne dépendent d’aucune promesse de marque. Utilisez un mot de passe de test jetable — password, ou une chaîne temporaire jamais utilisée sur un compte. Ne collez pas un mot vivant dans une démo.
- Ouvrez l’onglet Réseau des outils de développement et activez Conserver le journal / Preserve log. Filtrez d’abord Fetch / XHR, puis parcourez documents et autres requêtes.
- Rechargez la page de contrôle. Vous devez voir une liste statique (sur ce site,
leaked-top10k.txt). Ouvrez cette requête : la réponse est un mot de passe par ligne, et le corps de requête doit être vide. - Saisissez le mot de test dans le champ et attendez un résultat. Inspectez les nouvelles requêtes : l’URL, la query, le JSON et les champs de formulaire ne doivent pas contenir la chaîne que vous venez de taper.
- Cherchez dans le panneau
pwnedpasswords,hibpetrange/. Un modèle à liste locale ne doit pas toucher ces hôtes. S’il le fait, la page a lancé une requête de plage — lisez la section précédente au lieu de la traiter comme « entièrement locale ». - Parcourez les requêtes d’analytics (les chemins contiennent souvent
matomooucollect). Les noms d’événements peuvent dire Faible / Moyen / Fort. Les valeurs ne doivent pas inclure le mot de passe. - Pour comparer un modèle à corpus entier, rejouez le même mot jetable sur une page qui appelle HIBP. Vous devez voir un GET vers
api.pwnedpasswords.com/range/dont le chemin n’est que cinq caractères hexadécimaux.
Coupez le réseau et saisissez une seconde fois. C’est un contrôle utile en plus pour un modèle local : si le lexique est déjà en cache, force et correspondances de liste doivent encore se calculer ; une requête de plage doit échouer. Ne prenez pas « zéro requête » comme seule note de passage — la première visite doit charger le lexique, et ce n’est pas le même trafic qu’un POST du mot de passe. L’article précédent utilisait le même panneau pour le chiffrement local. Ici, vous surveillez une chose de plus : si une requête métier porte votre saisie.
Erreurs fréquentes : barre verte, « tout le web », et « j’ai déjà vérifié »
« La barre est verte, donc ça n’a pas fuité » ne tient pas. Le vert décrit un espace de caractères. Une fuite décrit si quelqu’un d’autre tient déjà la même chaîne. Les deux peuvent être vrais en même temps.
« C’est écrit calcul local, donc rien n’a quitté l’onglet » ne tient pas non plus. Une liste locale télécharge un lexique. Une requête de plage télécharge un seau de hachages. Ce que vous voulez interdire, c’est que l’original — et le hachage complet — partent comme donnée métier. Vous n’avez pas à interdire chaque requête HTTP.
« Ça n’apparaît pas dans HIBP, donc je peux le réutiliser sur tous les sites » est l’erreur chère. Le credential stuffing essaie un mot de passe contre beaucoup de sites. Il n’exige pas que ce mot figure dans le top mille public. Ni une liste locale ni une requête de corpus entier ne règle la réutilisation. Générez un nouveau mot de passe sur cet appareil, prenez le défaut aléatoire de 16 caractères ou plus, et stockez une chaîne différente par site.
Coller un mot de passe dans un chat pour qu’un collègue « voie s’il est fort » transforme un contrôle en fuite. Quand vous devez remettre un nouveau mot à quelqu’un d’autre, placez un secret court sur un lien à usage unique et gardez la clé après # dans l’URL. Un fichier que vous déchiffrerez plus d’une fois va dans la boîte de chiffrement de fichier. La page de contrôle répond à « regardez vous-même la liste et la barre ». Ce n’est pas un canal d’échange de clés.
Par où commencer
Commencez par un mot de passe que vous comptez déjà retirer, ou qui n’a jamais servi sur un vrai compte. Ouvrez la page de contrôle, regardez la requête de lexique dans Réseau, saisissez, puis confirmez que la chaîne n’est pas partie. Si elle figure dans la liste, ne gardez pas deux caractères et ne la réutilisez pas. Ouvrez le générateur de mot de passe et créez-en un sur cet appareil, longueur 16 ou plus. Un échec signifie seulement qu’il n’est pas membre de cet ensemble public de mots faibles. Stockez quand même un mot différent par site.
Si la question que vous avez vraiment est « ce mot de passe a-t-il figuré dans une grande fuite connue », environ 860 lignes locales ne suffisent pas. Utilisez un outil qui lance une requête de plage en k-anonymat, et confirmez dans Réseau que seuls 5 caractères de préfixe sont partis. Ne remettez pas l’original à une page de recherche inconnue. Après les deux contrôles, souvenez-vous : un outil qui s’ouvre sans inscription ne remplace pas la protection de connexion de chaque site, et il ne prouve pas qu’un serveur ne fuira jamais plus tard.
Une fois cela fait, vous pouvez déjà répondre au titre. Une liste locale de fuites prouve « cela ressemble-t-il au lot que les attaquants essaient en premier ». Une requête mot de passe « tout le web » — si elle est bien implémentée — prouve « le hachage complet figure-t-il dans le corpus qu’ils tiennent ». La première envoie un lexique et garde le mot de passe. La seconde envoie un préfixe et garde l’original. Un troisième modèle qui envoie l’original en POST n’appartient à ni l’un ni l’autre.
Questions fréquentes
Si la liste locale échoue, faut-il encore passer par Have I Been Pwned ?
Cela dépend de la phrase dont vous avez besoin. Un échec signifie seulement que la chaîne n’est pas sur cette liste publique de mots faibles. Si vous voulez aussi savoir si elle figure dans le corpus de hachages de HIBP, lancez une requête de plage à part et confirmez dans Réseau que seuls 5 caractères de préfixe sont partis. Gardez les deux contrôles séparés. Ne les fusionnez pas en « j’ai déjà cherché sur tout le web ».
Une requête de plage dit-elle mon mot de passe à HIBP ?
Selon le modèle officiel et le texte de Troy Hunt, l’autre côté reçoit les cinq premiers caractères d’un hachage SHA-1 ou NTLM — pas le mot de passe, et pas le hachage complet. La correspondance se termine dans votre navigateur. C’est encore une requête sortante. Si vous n’acceptez qu’aucun préfixe ne quitte l’appareil, n’utilisez que la liste locale et acceptez la couverture plus étroite.
Faut-il un compte pour contrôler un mot de passe ? Le candidat est-il envoyé ?
Aucun compte. Sur un modèle local, le candidat doit rester dans le champ. Ce qui peut partir, c’est le fichier de lexique, plus des événements d’analytics qui ne contiennent pas l’original. Qu’une page le fasse vraiment est une question de Réseau, pas une ligne « nous n’envoyons rien » sur la page.
Peut-on croire « cassage hors ligne : N années » sur la barre de force ?
Ce chiffre est un ordre de grandeur à un rythme d’essais fixe. Ce n’est pas la mesure d’un GPU particulier ni d’une attaque par dictionnaire. Quand la liste correspond, les attaquants ne suivront pas cette horloge. Traitez-le comme un rappel que la chaîne est courte ou utilise trop peu de classes — pas comme une garantie de sécurité.