Contournement du TokenGuard de Laravel : êtes-vous exposé, que lancer ?
Laravel News a signalé le 2026-10-20 un avis de sécurité critique, GHSA-f9x3-7vq9-cph6, avec un score CVSS de 9.2, dans Illuminate\Auth\TokenGuard, la classe derrière le driver de guard token. Sur MySQL et MariaDB, un attaquant sans compte pouvait être authentifié comme un utilisateur existant sans connaître son jeton d'API. Si vous faites tourner Laravel, la question utile n'est pas de savoir à quel point cela paraît grave, mais si votre application utilise ce guard, et la réponse tient dans un seul fichier.
Ce qui n'allait pas
D'après l'avis tel que le décrit Laravel News, le guard vérifiait seulement que le jeton extrait de la requête n'était pas vide avant de le passer au user provider. Une valeur spécialement construite, qui n'était pas une chaîne, passait ce contrôle, et la recherche qui suivait trouvait un enregistrement utilisateur qu'elle n'aurait jamais dû trouver au lieu d'échouer. La découverte est attribuée à Hristijan Manasijev. Le correctif ajoute une vérification de type dans user() et dans validate() : tout ce qui n'est pas une chaîne est rejeté avant qu'une requête ne parte.
// before (simplified): only emptiness was checked
if (! empty($token)) { ... }
// after (as quoted in the report): the type is checked first
if (is_string($token) && ! empty($token)) { ... }
Pourquoi une valeur non textuelle est dangereuse dans une recherche
Cette partie explique la catégorie de bug en général, pas le mécanisme confirmé de cet avis. En PHP, une entrée de requête n'est pas toujours une chaîne. Une query string ou un corps JSON peut transporter un tableau là où votre code attend une valeur unique, et les query builders traitent souvent un tableau comme "plusieurs valeurs" ou "plusieurs conditions" plutôt que comme un jeton à comparer. Un code qui se contente de demander "est-ce vide ?" laisse passer ce tableau, et la recherche répond alors à une autre question que celle que vous vouliez poser. La parade est banale et fiable : vérifiez le type de chaque entrée qui ressemble à un identifiant, à la frontière, avant qu'elle ne touche une requête.
Êtes-vous exposé ? Ouvrez config/auth.php
Selon l'avis, vous n'êtes concerné que si un guard de config/auth.php utilise le driver token, par exemple 'api' => ['driver' => 'token', 'provider' => 'users']. Sanctum et Passport enregistrent leurs propres drivers de guard et ne figurent pas dans l'avis. Les versions corrigées sont Laravel 12.68.0 et 13.29.0, datées toutes deux du 2026-08-25 dans l'article de Laravel News ; chaque version antérieure est listée comme affectée, et les correctifs n'existent que pour les branches 12.x et 13.x. Si vous êtes sur une version majeure plus ancienne et utilisez le driver token, le correctif passe par une montée de version majeure.
Le même jour est arrivé un second avis, de gravité moyenne, GHSA-5wcm-3v2w-8362 avec un CVSS de 6.5, dans les ressources JSON:API ajoutées en 12.45 : une requête en lecture seule pouvait être construite pour déclencher une opération destructrice sur une table liée. Laravel News indique 12.68.0 et 13.27.0 comme versions corrigées pour celui-là, donc la même mise à jour couvre les deux.
Ce qu'il faut lancer
composer update laravel/framework
composer audit
Ajoutez aussi composer audit à la CI, pour que le prochain avis apparaisse comme un build en échec et non comme un article que vous tombez par hasard en train de lire. Pour ce site, j'ai vérifié les deux points : composer.lock fixe laravel/framework en v13.35.0, au-delà de 13.29.0, et config/auth.php ne définit qu'un guard session, donc il n'y a pas de guard token ici au départ. Si vous construisez une nouvelle API, Sanctum est un choix par défaut plus sûr que le guard à jeton nu, et quel que soit votre choix, vérifiez que chaque identifiant est une chaîne avant qu'il n'atteigne une requête.
Ce que disent les lecteurs