security
La limitation de débit, et qui compte comme un seul appelant
La limitation de débit, et qui compte comme un seul appelant
@nestjs/throttler est le module officiel de limitation de débit de NestJS. Il suit les requêtes par client — par IP par défaut — dans une fenêtre glissante, et rejette au-delà d'une limite configurée avec un 429.
ThrottlerModule.forRoot([{ ttl: 60000, limit: 10 }]);
@Throttle({ default: { limit: 3, ttl: 60000 } })
@Post("login")
login() { ... }
Les endpoints de connexion et d'authentification ont besoin de limites plus serrées que le reste de l'API. Un endpoint général peut tolérer 100 requêtes/minute par client ; un endpoint de connexion est la cible du credential stuffing. Limiter la connexion en particulier — une poignée par minute par IP, plus serré par compte — est peu coûteux et à haute valeur, et ça se place devant la logique de verrouillage au niveau application, arrêtant le volume de l'attaquant avant même d'arriver au point de vérifier les identifiants.
Deux choses qui ne sont pas évidentes
Le stockage en mémoire par défaut ne marche correctement qu'avec une seule instance. Avec plusieurs répliques derrière un load balancer, chacune suit ses propres compteurs, donc la limite effective devient la limite configurée fois le nombre d'instances, sans erreur nulle part. Une vraie limitation distribuée a besoin d'un stockage partagé — un adaptateur adossé à Redis garde chaque instance qui compte contre le même état.
La limitation par IP seule ne suffit pas — et peut être activement nuisible. J'ai trouvé ce raisonnement en réfléchissant à si le back-end était sûr à clusteriser : le défaut était clé sur req.ip pour chaque route, y compris les authentifiées. En production, chaque utilisateur sur le même WiFi de bureau et chaque membre du personnel derrière le même NAT partageraient un budget — un utilisateur intensif pouvait discrètement étrangler tous les autres, indiscernable d'une attaque. Le correctif se clé sur l'identité de l'utilisateur authentifié quand il y en a une, retombant sur l'IP seulement pour les requêtes pas encore connectées. Il a fallu un petit réordonnancement de la chaîne de guards, pour que l'auth remplisse req.user avant que le throttler ne tourne.
La limitation est une couche. Associe-la à un verrouillage de compte après N échecs, un CAPTCHA sur les échecs répétés, et une surveillance des motifs inhabituels. La limitation de débit ralentit un attaquant ; elle n'arrête pas un attaquant patient.