Tous les articles

Contournement du TokenGuard de Laravel : êtes-vous exposé, que lancer ?

Sécurité · 4 min de lecture ·

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)) { ... }
Jeton issu de la requête Est-il vide ? Non, on continue Recherche utilisateur Mauvais compte ouvert aucun test de type chaîne une valeur non textuelle atteint la base de données
Avant le correctif : le seul filtre demande si la valeur est vide, jamais de quel type elle est.

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.

Jeton issu de la requête is_string et non vide ? oui Recherche avec une seule chaîne non Rejeté, aucune requête
Après le correctif : le type est vérifié d'abord, donc un tableau n'atteint jamais la base.

Ê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.

Cherchez 'token' dans config/auth.php. Si aucun guard n'utilise ce driver, cet avis ne vous concerne pas, mais mettez à jour quand même : celui sur JSON:API pourrait vous concerner.

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.

Source : Laravel News, « Laravel token guard auth bypass ».

Ce que disent les lecteurs

  1. Pas encore de mot. Le premier est toujours le plus courageux.
Vous construisez quelque chose du genre ? Je peux vous aider. Écrivez-moi sur WhatsApp