---
title: "Вразливості в PHPUnit 13.4 і symfony/yaml: що оновити в Laravel-проєкті"
url: https://laravelukraine.com/blog/vrazlivosti-v-phpunit-134-i-symfonyyaml-shho-onoviti-v-laravel-projekti
date: 2026-11-09
---

# Вразливості в PHPUnit 13.4 і symfony/yaml: що оновити в Laravel-проєкті

Наприкінці жовтня GitHub Advisory Database додала дві вразливості в пакетах, які часто трапляються в Laravel-проєктах. [GHSA-9vw2-f4vp-x7gf](https://github.com/advisories/GHSA-9vw2-f4vp-x7gf) (CVE-2026-119193, середня серйозність) - у PHPUnit 13.4: інший користувач тієї самої машини міг виконати свій код із правами розробника. [GHSA-2v3c-qxhr-7vpv](https://github.com/advisories/GHSA-2v3c-qxhr-7vpv) (CVE-2026-109413, висока) - у `symfony/yaml`: один документ вичерпує стек і валить процес.

Жодна з них не робить вразливим кожен Laravel-застосунок, як нещодавній [ReDoS у HttpFoundation](https://laravelukraine.com/blog/redos-u-symfony-httpfoundation-i-xxe-u-phpspreadsheet-shho-onoviti-v-laravel-projekti). Але одна зачіпає всіх, хто перейшов на Pest 5, і може зламати `composer audit` у CI.

### Що сталося в PHPUnit 13.4

PHPT - формат тестів, у якому код і очікуваний вивід лежать в одному файлі; його використовують автори бібліотек і розширень. Коли PHPT-тести запускаються зі збором покриття коду (PCOV або Xdebug), PHPUnit записує код тесту в окремий файл і виконує його в дочірньому процесі.

Починаючи з 13.4.0 ці файли опинялися в каталозі з фіксованою назвою - `sys_get_temp_dir() . '/phpunit-phpt'`, тобто `/tmp/phpunit-phpt` на Linux. Якщо каталог уже існував, PHPUnit використовував його, не перевіряючи власника і права. Інший користувач машини міг створити цей каталог заздалегідь, дочекатися появи файлу з тестом і підмінити його своїм кодом. Той виконувався з правами розробника, а потім запускав оригінальний тест, тож тест проходив, і звіт про покриття був повним. У [попередженні](https://github.com/sebastianbergmann/phpunit/security/advisories/GHSA-9vw2-f4vp-x7gf) є повний proof of concept.

[PHPUnit 13.4.4](https://github.com/sebastianbergmann/phpunit/releases/tag/13.4.4) створює для цих файлів каталог із непередбачуваною назвою, доступний лише поточному користувачеві, і не використовує каталог, який уже існує. У тому ж релізі виправили схожу проблему з каталогом кешу статичного аналізу, а 13.4.5 доробив цей фікс для систем без розширення POSIX.

### Хто насправді під загрозою

Щоб атака спрацювала, мають збігтися всі умови:

- PHPUnit 13.4.0-13.4.3. Версії 12.5 і старші не вразливі: вони пишуть тимчасові файли поруч із PHPT-тестом;
- у проєкті є PHPT-тести, і їх запускають зі збором покриття;
- `/tmp` спільний для кількох користувачів. macOS і Windows за замовчуванням використовують окремий тимчасовий каталог для кожного користувача, тож там проблеми немає;
- у зловмисника є обліковий запис на тій самій машині або контроль над процесом, що працює від іншого користувача, і він встиг створити каталог першим.

Будемо чесними: типовий Laravel-застосунок PHPT-тестів не має, а стандартний скелет `laravel/laravel` досі вимагає `phpunit/phpunit` `^12.5.12`, тобто вразливої гілки взагалі не ставить. Одноразовий контейнер у CI, де працює один користувач, теж не вразливий. Реальний ризик - на спільних dev-серверах і self-hosted CI-раннерах, де на одній машині працюють різні облікові записи, і для авторів пакетів, які тестують PHPT.

### Чому Pest 5 треба оновлювати окремо

Найпомітніше ця вразливість зачіпає користувачів [Pest 5](https://laravelukraine.com/blog/viisov-pest-5-z-analizom-vplivu-testiv-verifikacijeiu-agentiv-ta-ocinkami-llm). Pest закріплює PHPUnit на одній patch-версії: пара `require` і `conflict` у його `composer.json` не дозволяє взяти новішу. Pest 5.3.1, 5.3.2 і 5.3.3 прив'язані відповідно до 13.4.1, 13.4.2 і 13.4.3 - тобто саме до вразливих версій. Тому `composer update phpunit/phpunit` нічого не дасть, доки ви на старому Pest.

Як пояснено в [PR із фіксом](https://github.com/pestphp/pest/pull/1995), через це `composer audit` падає на попередженні і ламає CI, а Composer, який блокує встановлення версій із відомими вразливостями, на гілці 5.x взагалі не міг розв'язати залежності без `--no-blocking`. [Pest 5.3.4](https://github.com/pestphp/pest/releases/tag/v5.3.4) підняв PHPUnit одразу до 13.4.5, а не до 13.4.4, бо, за словами автора PR, 13.4.5 доводить фікс до систем без розширення POSIX. Поточний Pest 5.3.5 теж вимагає `^13.4.5`.

```bash
composer show pestphp/pest phpunit/phpunit
composer update pestphp/pest --with-all-dependencies
```

Якщо ви на PHPUnit 13.4 без Pest, достатньо звичайного `composer update phpunit/phpunit`.

### symfony/yaml: коротко, що нового

Про цю вразливість ми вже коротко писали в [огляді 28 жовтня](https://laravelukraine.com/blog/redos-u-symfony-httpfoundation-i-xxe-u-phpspreadsheet-shho-onoviti-v-laravel-projekti): `Yaml\Parser::lexInlineStructure()` рекурсивно розбирав вкладені inline-колекції на кшталт `[[[[...]]]]`, не враховуючи `maxNestingLevel`, і достатньо глибокий документ вичерпував стек. Тепер [лексер рахує ту саму глибину](https://github.com/symfony/symfony/pull/65688), що й решта парсера, і за межею кидає `ParseException`. Виправлені версії: 5.4.54, 6.4.45, 7.4.18 і 8.1.6, так само для `symfony/symfony`.

Кілька деталей, які варто додати:

- Фікс злили ще 29 серпня як «hardening», а 6.4.45, 7.4.18 і 8.1.6 вийшли 30 серпня. Попередження опублікували лише 27 жовтня. Якщо ви оновлювали Symfony-пакети з вересня, на гілках 6.4-8.1 виправлення, найімовірніше, вже стоїть.
- Сам Laravel `symfony/yaml` не потребує, але пакет часто приходить транзитивно. Наприклад, його напряму вимагають `darkaonline/l5-swagger`, `zircote/swagger-php` і `knuckleswtf/scribe`. Вони розбирають ваші власні специфікації, а не дані від відвідувачів, тож саме по собі це не робить застосунок вразливим.
- Найгірший сценарій у Symfony-світі - `#[MapRequestPayload]` без обмеження `acceptFormat`: там вистачало одного неавтентифікованого запиту з YAML. У Laravel аналога немає, тож ризик з'являється лише тоді, коли ваш код сам викликає `Yaml::parse()` на тому, що надіслав користувач: імпорт конфігурацій, OpenAPI-специфікацій, front matter.

```bash
composer why symfony/yaml
composer update symfony/yaml
```

### Що зробити сьогодні

- Запустіть `composer audit`: обидва попередження вже в базі, і він покаже, чи вони стосуються вас.
- На Pest 5 оновіть сам Pest до 5.3.4 або новішого: PHPUnit підтягнеться разом із ним.
- На PHPUnit 13.4 без Pest оновіться до 13.4.4 або новішого. На PHPUnit 12.5 нічого робити не треба.
- Якщо тести ганяються на спільній машині, сенс має й ширший захід: окремий `TMPDIR` для кожного користувача або `PrivateTmp` у systemd закривають увесь клас таких атак, а не лише цю.
- `symfony/yaml` оновіть, якщо він є в `composer.lock`, і окремо перевірте, чи застосунок приймає YAML від користувачів.
