metalfrom.eu/apps/api/test
Nicolas FRYDER a21bd55a90 fix(sécurité): verrouillage de compte détournable, et Vary manquant sur le CORS
isLockedOut comptait `username = $2 OR ip = $3` dans un seul total. Cinq échecs
avec le nom d'un admin, depuis n'importe quelle adresse, verrouillaient donc ce
compte un quart d'heure — à répéter indéfiniment, sans coût et sans connaître
le mot de passe. Il suffisait de connaître le nom d'utilisateur pour mettre
l'admin dehors en permanence.

Les deux compteurs deviennent distincts et volontairement asymétriques. L'IP
reste stricte à 5 : c'est elle qui freine la force brute, et s'auto-verrouiller
n'a aucun intérêt pour un attaquant. Le compteur par username subsiste contre
une attaque répartie, mais à 20 — il faut brûler 4 IP avant de commencer à
gêner le titulaire du compte. Vérifié contre PostgreSQL : l'admin légitime a
bien par_ip=0 quand un tiers martèle depuis ailleurs.

Ajoute par ailleurs `Vary: Origin` aux réponses CORS. L'en-tête Allow-Origin
dépend de l'origine demandée : sans Vary, un cache intermédiaire peut servir à
une origine la réponse mise en cache pour une autre — ce qui revient à
autoriser une origine qui ne l'est pas, ou à faire refuser une origine
légitime. Posé aussi quand l'origine est refusée, pour la même raison.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 14:24:33 +02:00
..
helpers feat(qualité): outillage de test complet, CI locale, annulation réelle des runs 2026-08-18 10:05:40 +02:00
integration fix(géocodage): les corrections manuelles n'étaient protégées par rien 2026-08-22 14:20:44 +02:00
adminAuth.test.js fix(sécurité): verrouillage de compte détournable, et Vary manquant sur le CORS 2026-08-22 14:24:33 +02:00
adminRoutes.test.js fix(admin): passe de debug guidée par la mutation — 4 bugs, mutation 64 → 68 % 2026-08-18 15:42:52 +02:00
adminRoutesCoverage.test.js feat: validation syntaxique du SQL + supervision des services de fond 2026-08-18 18:20:15 +02:00
bandFilters.test.js fix(admin): passe de debug guidée par la mutation — 4 bugs, mutation 64 → 68 % 2026-08-18 15:42:52 +02:00
cancellation.test.js feat(qualité): outillage de test complet, CI locale, annulation réelle des runs 2026-08-18 10:05:40 +02:00
conflicts.test.js fix(admin): passe de debug guidée par la mutation — 4 bugs, mutation 64 → 68 % 2026-08-18 15:42:52 +02:00
harness.test.js feat(qualité): outillage de test complet, CI locale, annulation réelle des runs 2026-08-18 10:05:40 +02:00
locations.test.js fix: sync du point principal + verrou de migration, redis mort retiré, tests par propriétés 2026-08-18 21:03:17 +02:00
publicRoutes.test.js fix(sécurité): verrouillage de compte détournable, et Vary manquant sur le CORS 2026-08-22 14:24:33 +02:00
publicRoutesCoverage.test.js feat(qualité): outillage de test complet, CI locale, annulation réelle des runs 2026-08-18 10:05:40 +02:00
rateLimit.test.js fix(sécurité): plafond de /admin/import contournable en variant le jeton 2026-08-22 13:15:12 +02:00
sqlSyntax.test.js fix: sync du point principal + verrou de migration, redis mort retiré, tests par propriétés 2026-08-18 21:03:17 +02:00
validate.property.test.js fix: sync du point principal + verrou de migration, redis mort retiré, tests par propriétés 2026-08-18 21:03:17 +02:00
validate.test.js feat(qualité): outillage de test complet, CI locale, annulation réelle des runs 2026-08-18 10:05:40 +02:00