Authentification : force brute, politique de mots de passe et identifiants par défaut
L'authentification est le mécanisme qui vérifie qu'un utilisateur est bien celui qu'il prétend être. C'est le premier contrôle de sécurité d'une application, et l'un des plus fréquemment mal implémenté. Les faiblesses ici permettent à un attaquant d'accéder à des comptes sans connaître le mot de passe, par force brute, par devinette ou en exploitant des configurations laissées par défaut.
Absence de protection contre la force brute
Sans limitation du nombre de tentatives de connexion, un attaquant peut essayer des milliers de combinaisons sans friction. Avec un dictionnaire de mots de passe courants (rockyou.txt contient 14 millions d'entrées), il suffit de quelques minutes pour compromettre un compte dont le mot de passe est faible. Sur une interface accessible depuis internet, cette attaque est triviale à automatiser.
Les protections à mettre en place ne sont pas exclusives, elles se combinent : verrouillage temporaire après N échecs (ex. 5 tentatives, 15 minutes de blocage), CAPTCHA après un certain seuil, délai progressif entre les tentatives, alerte à l'utilisateur lors de tentatives suspectes.
Exemple : verrouillage côté serveur (Node.js / Redis)
const MAX_ATTEMPTS = 5;
const LOCK_DURATION = 15 * 60; // 15 min en secondes
async function checkLoginAttempts(email) {
const key = `login_attempts:${email}`;
const attempts = await redis.incr(key);
if (attempts === 1) await redis.expire(key, LOCK_DURATION);
if (attempts > MAX_ATTEMPTS) {
const ttl = await redis.ttl(key);
throw new Error(`Compte verrouillé. Réessayez dans ${ttl} secondes.`);
}
}
Attention au verrouillage permanent : un verrouillage qui n'expire jamais ouvre la porte à un déni de service. Un attaquant peut verrouiller délibérément tous les comptes en soumettant des tentatives échouées. Préférez un verrouillage temporaire ou progressif.
Identifiants par défaut inchangés
Les équipements réseau, les CMS, les interfaces d'administration et les logiciels embarqués sont livrés avec des identifiants par défaut documentés publiquement. admin/admin, admin/password, root/root : ces combinaisons sont les premières testées par tout attaquant, et elles fonctionnent bien plus souvent qu'on ne le croit. Des bases de données publiques comme defaultpassword.de ou CIRT.net référencent les identifiants par défaut de milliers de produits.
La correction est évidente mais régulièrement négligée : changer les identifiants par défaut lors de la mise en service, idéalement forcer ce changement lors de la première connexion. Pour les équipements réseau, inclure ce point dans la checklist de déploiement.
Politique de mots de passe insuffisante
Une politique de mots de passe insuffisante accepte des mots de passe triviaux qui seront compromis rapidement. Les erreurs courantes : longueur minimale trop faible (6 ou 8 caractères), absence de vérification contre des dictionnaires de mots de passe courants, règles de complexité arbitraires qui n'améliorent pas réellement la sécurité ("au moins une majuscule"), absence de limite supérieure raisonnable.
Les recommandations actuelles du NIST (SP 800-63B) vont à contre-courant des idées reçues : privilégier la longueur (au moins 8 caractères, idéalement 12 ou plus), vérifier que le mot de passe ne figure pas dans une liste de mots de passe compromis, ne pas imposer de rotation périodique forcée (qui incite les utilisateurs à faire des variations prévisibles), autoriser tous les caractères Unicode.
Vérification contre les mots de passe compromis (HaveIBeenPwned API)
// k-anonymity : seuls les 5 premiers caractères du hash SHA-1 sont envoyés
async function isPwnedPassword(password) {
const hash = crypto.createHash('sha1').update(password).digest('hex').toUpperCase();
const prefix = hash.slice(0, 5);
const suffix = hash.slice(5);
const res = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`);
const text = await res.text();
return text.split('\n').some(line => line.startsWith(suffix));
}
Stockage de mots de passe en clair
Stocker des mots de passe en clair ou avec un hash non salé (MD5, SHA-1) est une erreur grave qui transforme toute compromission de base de données en compromission totale des comptes. Un dump de base de données avec des mots de passe en clair permet à l'attaquant de se connecter immédiatement à tous les comptes, y compris sur d'autres services si les utilisateurs réutilisent leurs mots de passe.
Les algorithmes de hachage génériques (MD5, SHA-256) ne sont pas adaptés au stockage de mots de passe : ils sont conçus pour être rapides, ce qui facilite les attaques par force brute. Utiliser des algorithmes spécialement conçus pour ce cas : bcrypt, Argon2 (recommandé), scrypt.
Hachage sécurisé avec Argon2 (Node.js)
const argon2 = require('argon2');
// Lors de la création / modification du mot de passe :
const hash = await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: 2 ** 16, // 64 Mo
timeCost: 3,
parallelism: 1,
});
// Lors de la vérification :
const valid = await argon2.verify(storedHash, password);
Mécanisme de changement de mot de passe mal sécurisé
Le formulaire de changement de mot de passe doit exiger la confirmation de l'ancien mot de passe avant d'accepter le nouveau. Sans cette vérification, un attaquant qui accède brièvement à une session authentifiée (via une XSS, un accès physique ou une session non invalidée) peut changer le mot de passe et prendre le contrôle permanent du compte.
Après un changement de mot de passe réussi : invalider toutes les autres sessions actives (sauf la courante si l'on souhaite maintenir l'utilisateur connecté), envoyer une notification par email, journaliser l'événement.
Récapitulatif
- Limiter les tentatives de connexion : verrouillage temporaire après N échecs, délai progressif ou CAPTCHA
- Changer les identifiants par défaut : dès la mise en service, forcer le changement à la première connexion
- Politique de mots de passe fondée sur la longueur : au moins 12 caractères, vérification contre des listes de mots de passe compromis
- Hacher avec Argon2 ou bcrypt : jamais MD5, SHA-1 ou SHA-256 seuls pour les mots de passe
- Exiger l'ancien mot de passe lors du changement : invalider les autres sessions après le changement
Pour aller plus loin
Une question après la lecture ?
Des doutes sur la solidité de votre authentification ? Envoyez un message.
Ou réservez directement un cadrage de 30 minutes
Réserver un appel →