Mesure et instrumentation
Construire un compteur de force Javascript Password pour une meilleure sécurité
Table of Contents
La construction d'applications Web sécurisées exige plus que la simple sécurité de l'arrière-plan; l'avant-plan joue un rôle essentiel pour guider les utilisateurs vers un comportement plus sûr. L'un des moyens les plus efficaces pour améliorer l'hygiène des mots de passe est un compteur de force de mot de passe en temps réel qui donne une rétroaction immédiate et concrète.
Pourquoi un compteur de force mot de passe compte
Selon le NCSC, de nombreux utilisateurs comptent toujours sur des modèles prévisibles comme le mot de passe123. Un compteur de force permet aux utilisateurs de trouver des mots de passe plus longs et plus complexes sans les obliger à comprendre les calculs d'entropie.
Un compteur mal conçu pourrait qualifier "Mot de passe1!" de fort (quand il est en fait courant) ou décourager les utilisateurs avec des règles trop strictes. Les meilleurs compteurs équilibrent la complexité avec la facilité d'utilisation et utilisent plusieurs couches d'analyse.
Critères de base pour évaluer la force du mot de passe
Avant d'écrire un code, définissez ce qui rend un mot de passe « fort ». Des règles simples comme la longueur et la diversité des caractères sont un début, mais les modèles de menace modernes tiennent également compte des motifs, des mots de dictionnaire et des substitutions communes. Pour ce projet, nous allons mettre en place un système de notation basé sur les facteurs suivants, suivant de près les lignes directrices de NIST SP 800-63B:
- Longueur : Minimum 8 caractères, avec des récompenses croissantes allant jusqu'à 20 caractères.
- Variété de caractères: majuscule, minuscule, chiffres, caractères spéciaux.
- Caractères répétés: Sanctions pour des séquences comme "aaa".
- Des motifs communs: Des marches simples du clavier ("qwerty"), des dates, ou des mots communs.
- Estimation entropie: Résistance bit basée sur un ensemble de caractères et une longueur possibles.
Pour un système de production, envisagez d'intégrer une bibliothèque comme zxcvbn de Dropbox, qui utilise la correspondance de motifs et l'analyse de fréquence. Pour cet article, nous allons construire un scoreur personnalisé qui couvre les trois premiers critères – assez pour de nombreux cas d'utilisation – et ensuite montrer comment l'étendre avec zxcvbn.
Architecture du compteur de force mot de passe
Le compteur se compose de trois couches:
- Structure HTML[ – Champ d'entrée, zone de rétroaction en direct et barre de progression visuelle.
- Calcisme CSS[ – segments codés en couleurs et indicateurs d'accessibilité.
- JavaScript logique – Gestion des événements, notation et mises à jour de l'interface utilisateur avec débonflage pour la performance.
Nous allons le construire comme un composant autonome qui peut être déposé dans n'importe quelle forme. Pas de cadres requis – juste vanillé JavaScript.
Étape 1: Structure HTML avec accessibilité dans l'esprit
Utilisez le HTML5 sémantique avec les régions afin que les lecteurs d'écran annoncent des changements de force. Le compteur devrait comprendre à la fois une partition numérique (cachée peut-être) et une barre de progression visible.
<div class="password-field">
<label for="password">Choose a password:</label>
<input type="password" id="password" autocomplete="new-password" />
<div class="strength-meter" role="status" aria-live="polite">
<div class="strength-bar" id="strength-bar"></div>
<span class="strength-text" id="strength-text">Weak</span>
</div>
</div>
Le assure que les changements dynamiques sont annoncés sans interrompre l'utilisateur. Le le marque comme une région vivante.
Étape 2: Styling CSS pour une rétroaction visuelle claire
Utilisez une barre linéaire de progression du gradient qui change de couleur : rouge à jaune à vert. Inclure une animation subtile pour attirer l'attention. Gardez-la simple et accessible – assurer un contraste de couleur suffisant.
.strength-meter {
margin-top: 0.5rem;
height: 1rem;
border-radius: 4px;
background-color: #e0e0e0;
}
.strength-bar {
height: 100%;
width: 0%;
border-radius: 4px;
transition: width 0.3s ease, background-color 0.3s ease;
}
.strength-text {
display: block;
margin-top: 4px;
font-weight: bold;
font-size: 0.9rem;
}
Étape 3: Logique JavaScript – Score Algorithme
Implémentez une fonction qui renvoie une note (0–100) et un label correspondant. Nous récompenserons fortement la longueur, donnerons des points pour la diversité des caractères, et soustraireons pour les répétitions.
function evaluateStrength(password) {
let score = 0;
// Length bonuses (exponential)
if (password.length >= 8) score += 20;
if (password.length >= 12) score += 20;
if (password.length >= 16) score += 20;
if (password.length >= 20) score += 20;
// Character variety
if (/[a-z]/.test(password)) score += 5;
if (/[A-Z]/.test(password)) score += 5;
if (/[0-9]/.test(password)) score += 5;
if (/[^a-zA-Z0-9]/.test(password)) score += 10;
// Penalty for repeated characters (3+ consecutive same)
const repeats = password.match(/(.)\1{2,}/g);
if (repeats) {
const penalty = repeats.reduce((acc, seq) => acc + seq.length, 0) * 2;
score = Math.max(0, score - penalty);
}
// Clamp score to 0–100
return Math.min(100, Math.max(0, score));
}
function getStrengthLabel(score) {
if (score < 30) return 'Weak';
if (score < 60) return 'Moderate';
if (score < 85) return 'Strong';
return 'Very Strong';
}
Cet algorithme est léger et fonctionne en millisecondes même sur des mots de passe longs. Pour une application de production, envisager d'ajouter une évaluation basée sur le timeout pour éviter de bloquer le thread principal sur des entrées extrêmement longues (bien que rare).
Étape 4 : Dénonciation des événements d'entrée
L'évaluation de firing sur chaque frappe peut causer des problèmes de performance, surtout si vous vous intégrez à une bibliothèque lourde comme zxcvbn. Utilisez une fonction debonce pour retarder l'évaluation jusqu'à ce que l'utilisateur arrête de taper pendant 300ms.
const input = document.getElementById('password');
const strengthBar = document.getElementById('strength-bar');
const strengthText = document.getElementById('strength-text');
let debounceTimer;
input.addEventListener('input', function() {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
const score = evaluateStrength(this.value);
updateUI(score);
}, 300);
});
function updateUI(score) {
const label = getStrengthLabel(score);
strengthBar.style.width = score + '%';
strengthBar.style.backgroundColor = getColor(score);
strengthText.textContent = label;
}
function getColor(score) {
if (score < 30) return '#e53935'; // red
if (score < 60) return '#fb8c00'; // orange
if (score < 85) return '#43a047'; // green
return '#1b5e20'; // dark green
}
Étape 5: Amélioration avancée – Intégration zxcvbn
Les évaluateurs personnalisés ne passent pas compte des modèles de mot de passe communs. La bibliothèque de Dropbox zxcvbn utilise un dictionnaire de fréquence et un modèle correspondant pour produire une note plus précise. Pour l'intégrer, chargez la bibliothèque via CDN et remplacez la logique d'évaluation tout en conservant la même interface utilisateur.
<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>
Puis dans le rappel de débonflement :
const result = zxcvbn(this.value);
const score = result.score; // 0-4
updateUI(score * 25); // map to 0-100
Vous pouvez également afficher des suggestions de pour guider les utilisateurs vers des mots de passe plus forts.
Étape 6 : Intégration et rétroaction des formulaires
Ne vous arrêtez pas au compteur. Liez-le au gestionnaire de soumission du formulaire. Si le score du mot de passe est trop bas, évitez la soumission et affichez un message. Implémentez également un "montrer le mot de passe" pour que les utilisateurs puissent voir leur entrée – cela réduit la frustration.
const showToggle = document.getElementById('show-password');
showToggle.addEventListener('change', function() {
input.type = this.checked ? 'text' : 'password';
});
document.querySelector('form').addEventListener('submit', function(e) {
const score = evaluateStrength(input.value);
if (score < 30) {
e.preventDefault();
alert('Password is too weak. Please choose a stronger one.');
}
});
Considérations en matière de sécurité
Un compteur de force côté client est utile pour UX mais ne le traite jamais comme un mécanisme de sécurité. Toujours appliquer des politiques de mot de passe fortes du côté serveur. Ne jamais transmettre le mot de passe en texte simple au serveur pour l'évaluation – qui l'exposerait en transit. Utilisez HTTPS et hachage (bcrypt, argon2) pour le stockage. Le compteur ne devrait pas enregistrer ou stocker le mot de passe de quelque manière que ce soit.
Considérez également que la rétroaction du compteur pourrait être utilisée par un attaquant pour réduire l'espace de mot de passe s'il peut observer la sortie de l'interface utilisateur. Dans les environnements de haute sécurité, vous pouvez vouloir restreindre la rétroaction de force ou utiliser des estimations entropie sans révéler de score exact.
Essai du compteur de résistance de mot de passe
Écrire des tests unitaires pour la fonction de notation à l'aide de cas d'essai courants:
- "mot de passe" → Faible (score < 30)
- "P@ssw0rd123!" → Fort (score > 60)
- "a" → Faible
- "Correct-Horse-Batterie-Staple" → Très fort
- "11111111" → Faible (pénalité de caractères répétés)
Testez l'accessibilité en utilisant des lecteurs de navigation et d'écran de clavier. La région devrait annoncer des changements de force après une brève pause.
Optimisations des performances
Si vous utilisez zxcvbn, envisagez de le charger asynchronement avec l'attribut d'importation dynamique ou de report. Pour les mots de passe très longs (100 caractères+), limitez l'évaluation aux 100 premiers caractères pour éviter les ralentissements. La déclaration reste critique – fixez le délai à 250–400ms. Sur les appareils mobiles, envisagez de réduire le temps de débonflage à 200ms pour la réactivité.
Personnalisation et thème
Permet aux développeurs de dépasser les couleurs, les seuils et les poids de notation via un objet de configuration. Fournissez une interface callback pour que le compteur puisse être intégré avec des générateurs de mot de passe, des listes noires de mot de passe communes ou des calculatrices entropies.
function createStrengthMeter(inputEl, options = {}) {
const config = {
minLength: options.minLength || 8,
colors: options.colors || ['#e53935', '#fb8c00', '#43a047', '#1b5e20'],
thresholds: options.thresholds || [30, 60, 85]
};
// ... rest of the plugin logic
}
Conclusion
Construire un compteur de force de mot de passe JavaScript est un moyen pratique d'améliorer la sécurité des utilisateurs sans ajouter de friction. Les exemples de cet article fournissent une base solide: un algorithme de notation, la gestion des événements débonzée, HTML accessible et retour visuel. Pour les applications de production, envisager d'intégrer zxcvbn pour la détection avancée des motifs et toujours jumeler le compteur avec les politiques de mot de passe côté serveur.