27 жовтня GitHub Advisory Database додала дві групи попереджень, які прямо стосуються Laravel-проєктів. Перше - ReDoS у symfony/http-foundation (CVE-2026-108082): один неавтентифікований HTTP-запит із підготовленим заголовком Cache-Control займає процес майже на секунду. Друге - кілька вразливостей у PhpSpreadsheet, бібліотеці, на якій тримається Laravel Excel.
Обидва пакети ви, найімовірніше, не ставили напряму, тож у composer.json їх не видно. Саме тому такі попередження легко пропустити.
ReDoS у HttpFoundation: чому вразливий кожен Laravel-застосунок
Illuminate\Http\Request успадковує Symfony\Component\HttpFoundation\Request, а HeaderBag під час створення кожного запиту розбирає заголовок Cache-Control через HeaderUtils::split(). Регулярний вираз у цьому методі дозволяв ряду пробілів перед роздільником «розподілятися» між ітераціями зовнішнього повторення експоненційною кількістю способів, і рушій PCRE перебирав їх усі.
Цифри з попередження Symfony: 17 пробілів у заголовку на 8 КБ коштують 813 мс CPU на PHP 8.5, і кожен додатковий пробіл подвоює час. Від 18 пробілів preg_match_all() упирається в pcre.backtrack_limit і здається, а split() повертає порожній масив, тобто всі директиви заголовка мовчки зникають.
На практиці це дешевий DoS: щоб зайняти всі воркери PHP-FPM, вистачить кількох десятків паралельних запитів, і для цього не потрібні ні обліковий запис, ні конкретний маршрут. Заголовок розбирається до роутингу і middleware, тож rate limiting на рівні Laravel тут не допоможе.
Які версії Symfony брати
Діапазони вразливих версій охоплюють усе від 4.1 до свіжих релізів. Виправлення вийшли для підтримуваних гілок:
- 5.4: 5.4.54;
- 6.4: 6.4.48;
- 7.4: 7.4.21;
- 8.1: 8.1.9.
Формально попередження називає першими виправленими 6.4.46, 7.4.19 і 8.1.7, але, як визнає сама Symfony, перша версія фіксу зламала розбиття за пробільним роздільником: HeaderUtils::split('foo bar', ' ') у 6.4.46-6.4.47, 7.4.19-7.4.20 і 8.1.7-8.1.8 повертав одне значення замість двох. Тому орієнтуйтеся на версії зі списку вище. У гілці 5.4 цієї регресії не було.
Перевірте, що стоїть у проєкті:
composer show symfony/http-foundation
composer audit
Laravel 12 вимагає symfony/http-foundation ^7.2, Laravel 13 - ^7.4 || ^8.0, тож в обох випадках виправлена версія доступна без зміни обмежень:
composer update symfony/http-foundation --with-dependencies
Якщо після оновлення composer show все одно показує 7.2 чи 7.3, перевірте composer why-not symfony/http-foundation 7.4.21: ці гілки вже не підтримуються, і для них виправлень немає. Те саме з 6.0-6.3: треба переходити на 6.4, а це вимагає PHP 8.1.
Сусід: рекурсія в symfony/yaml
У тому ж пакеті попереджень Symfony опублікувала GHSA-2v3c-qxhr-7vpv (CVE-2026-109413). Inline-лексер YAML рекурсивно спускався в кожну { і [, не враховуючи maxNestingLevel, тож документ із глибоко вкладених колекцій вичерпував стек і валив процес.
Laravel сам по собі symfony/yaml не використовує, і YAML у запитах не розбирає. Вразливість актуальна, лише якщо ваш код викликає Yaml::parse() на даних від користувачів: імпорт конфігурацій, OpenAPI-специфікацій, front matter. Перевірити, чи пакет узагалі є в проєкті і хто його тягне:
composer why symfony/yaml
Виправлені версії: 5.4.54, 6.4.45, 7.4.18 і 8.1.6.
PhpSpreadsheet: хто під загрозою
PhpSpreadsheet читає XLSX, ODS і SpreadsheetML-XML, а перед розбором XML проганяє вміст через XmlScanner, який шукає <!DOCTYPE і відкидає файли з оголошеннями сутностей. Цього разу знайшлося три серйозні проблеми:
- GHSA-3x94-m842-937c: escape-послідовності ISO-2022 між символами
<!DOCTYPE ламають регулярний вираз сканера, а XML-парсер потім їх викидає і бачить звичайний DOCTYPE. Зачіпає XLSX, тобто найпоширеніший сценарій.
- GHSA-rxj4-h86g-25gc: читач SpreadsheetML (
Reader\Xml) сканує файл двічі і декодує сутності після кожної перевірки, тож подвійне кодування < проходить повз обидві. Лише гілки 3.3+ і 4.x-5.x.
- GHSA-j2w7-387v-m2rq: ODS-читач не обмежує атрибут
table:number-rows-repeated і створює по клітинці на кожен повтор. Файл на 1,4 КБ із 5 мільйонами рядків вичерпує пам'ять.
Для перших двох основний наслідок на сучасному PHP - DoS через розгортання сутностей: за даними попередження, XLSX на 2 КБ з'їдає близько 45 МБ пам'яті. Читання локальних файлів і SSRF через зовнішні сутності блокуються за замовчуванням на PHP 8 з libxml2 2.9+, але стають можливими на PHP 7 або якщо десь увімкнено LIBXML_NOENT.
Окремо є GHSA-2phh-27fw-q4gc середньої серйозності: обхід білого списку для зовнішніх зображень через HTTP-редирект. Він стосується лише тих, хто явно вмикає setAllowExternalImages(true).
Під загрозою застосунки, які відкривають таблиці від користувачів: імпорт товарів, контактів, прайсів. У Laravel-світі це насамперед Laravel Excel (maatwebsite/excel), який під капотом використовує PhpSpreadsheet.
Як оновити PhpSpreadsheet
Виправлені версії: 5.10.0, 3.10.8, 2.4.8, 2.1.19 і 1.30.7. Обмеження Laravel Excel дозволяють дістатися до них звичайним оновленням: гілка 3.1 вимагає phpoffice/phpspreadsheet ^1.30.5, актуальна 4.x - ^5.9.
composer show phpoffice/phpspreadsheet
composer update phpoffice/phpspreadsheet
Додатково варто звузити, які формати ви взагалі приймаєте. Якщо імпорт розрахований на XLSX і CSV, не дозволяйте ODS і XML у валідації і передавайте тип читача явно, а не покладайтеся на розширення файла:
$request->validate([
'file' => ['required', 'file', 'mimes:xlsx,csv', 'max:5120'],
]);
Excel::import(new ProductsImport, $request->file('file'), null, \Maatwebsite\Excel\Excel::XLSX);
Від обходу через ISO-2022 у XLSX це не захищає, тож оновлення обов'язкове, але прибирає з поверхні атаки два читачі, якими ви не користуєтеся. Важкий імпорт краще виносити в чергу з обмеженням пам'яті воркера: тоді «бомба» вб'є один процес, а не веб-сервер.
Якщо Laravel Excel у проєкті лише для експорту, ризик значно менший: вразливості сидять у читачах. А Fast Excel працює на OpenSpout, а не на PhpSpreadsheet, і ці попередження його не стосуються.
Що зробити сьогодні
- Запустіть
composer audit у кожному проєкті. Він знає про всі попередження з цієї статті.
- Оновіть
symfony/http-foundation до 5.4.54, 6.4.48, 7.4.21 або 8.1.9. Це стосується кожного Laravel-застосунку, без винятків.
- Якщо приймаєте таблиці від користувачів, оновіть
phpoffice/phpspreadsheet і звузьте список дозволених форматів.
symfony/yaml оновлюйте, якщо він є в composer.lock і розбирає чужі дані.
- Якщо
composer audit ще не працює у вашому CI, це хороший момент його туди додати: обидві бібліотеки - транзитивні залежності, про які інакше дізнаєшся з новин.