Laravel опублікував критичне попередження GHSA-f9x3-7vq9-cph6 (CVE-2026-114509, CVSS v4.0 9.2). Вбудований TokenGuard на MySQL і MariaDB дозволяв неавтентифікованому зловмиснику увійти як будь-який наявний користувач, не знаючи його API-токена. Того ж дня вийшло друге попередження, про JSON:API Resources. Обидві вразливості знайшов Христіян Манасієв (Hristijan Manasijev).
Найважливіше одразу: виправлення є в Laravel 13.29.0 і 12.68.0, які вийшли ще 25 серпня. Якщо ви оновлювали фреймворк після цієї дати, ви вже захищені. Попередження просто опублікували пізніше, щоб дати час оновитися.
Хто вразливий
Йдеться про Illuminate\Auth\TokenGuard - найпростіший API guard у Laravel, який шукає користувача за значенням стовпця api_token. Ваш застосунок його використовує, якщо в config/auth.php є guard на кшталт такого:
'guards' => [
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
Швидко перевірити всі проєкти можна так:
grep -rn "'driver' => 'token'" config/
composer show laravel/framework | grep versions
Нові застосунки такий guard зазвичай не використовують, але він досі живе в старих і внутрішніх API, які колись збудували "на швидку руку" і відтоді не чіпали. Саме їх варто перевірити першими, особливо якщо база - MySQL чи MariaDB.
Sanctum і Passport реєструють власні драйвери guard, і в попередження вони не входять. Як зазначає Laravel News, уражений лише драйвер token.
Наслідки, за словами попередження, - захоплення будь-якого облікового запису на маршрутах, захищених цим guard. Без жодного токена.
Що було не так і як це виправили
Попередження описує механізм стримано: зловмисник передає облікові дані не рядком, а значенням іншого типу, guard обробляє його неправильно, і на MySQL/MariaDB запит до бази знаходить не того користувача замість того, щоб відмовити в автентифікації.
До виправлення guard перевіряв лише те, що токен не порожній. Фікс додає перевірку типу в обидва місця, де токен потрапляє до провайдера користувачів, - у user() і validate():
// user()
if (is_string($token) && ! empty($token)) {
$user = $this->provider->retrieveByCredentials([
$this->storageKey => $this->hash ? hash('sha256', $token) : $token,
]);
}
// validate()
if (! is_string($credentials[$this->inputKey] ?? null) || empty($credentials[$this->inputKey])) {
return false;
}
Тести в тому самому коміті перевіряють, що з масивом замість рядка guard навіть не звертається до провайдера. Урок, корисний і поза цим випадком: дані з HTTP-запиту не обов'язково рядок, і порівнювати їх з базою без перевірки типу небезпечно.
Друга вразливість: JSON:API Resources
GHSA-5wcm-3v2w-8362 (CVE-2026-114508) має оцінку CVSS v3.1 6.5. Вона стосується JSON:API Resources, які з'явилися в Laravel 12.45 і стали частиною Laravel 13. Помилка - в обробці зв'язків, які клієнт просить включити у відповідь: за певних умов запит до ендпоінта лише для читання міг запустити руйнівну операцію над пов'язаною таблицею, аж до її повного очищення. Тобто користувач із правом лише на читання міг безповоротно знищити дані.
Вразливі версії 12.45.0-12.67.x і 13.x до 13.27.0. Виправлення змінює те, як JSON:API-ресурси завантажують запитані зв'язки, і вийшло в 12.68.0 та 13.27.0.
Що зробити
- Оновіть фреймворк: мінімум 13.29.0 або 12.68.0, а краще - до актуальної 13.x (на момент написання це 13.38.0):
composer update laravel/framework
composer audit
composer audit порівнює встановлені пакети з опублікованими попередженнями. Якщо його ще немає у вашому CI, це гарний привід додати.
- Перевірте
config/auth.php у всіх проєктах, включно з внутрішніми сервісами й адмінками. Пріоритет - ті, що працюють на MySQL або MariaDB.
- Виправлення TokenGuard випущені лише для гілок 12.x і 13.x. Якщо проєкт на Laravel 11 чи старішому і використовує драйвер
token, оновлення фреймворку - єдиний офіційний шлях. Доки ви його плануєте, варто подумати про перехід цього API на Sanctum.
- Якщо використовуєте JSON:API Resources, перегляньте логи на предмет несподіваних видалень у пов'язаних таблицях за період, коли працювала вразлива версія.
Обидві вразливості закриті вже два місяці, тож для тих, хто регулярно оновлює залежності, ця новина - нагадування, а не тривога. Для решти - привід зробити composer update сьогодні.