Spring4Shell: патч вышел, разворачиваем обновления по клиентам
Spring Framework 5.3.18/5.2.20 и Spring Boot 2.6.6 закрывают CVE-2022-22965. Разворачиваем патчи и считаем, что дал реестр Java-приложений, собранный после Log4Shell.
Spring Framework 5.3.18/5.2.20 и Spring Boot 2.6.6 выпущены с патчем CVE-2022-22965
Патчи вышли. VMware выпустила Spring Framework 5.3.18 и 5.2.20, следом подтянулся Spring Boot 2.6.6. CVE-2022-22965 закрыта на уровне фреймворка. Теперь основная работа - прокатить обновления по всем клиентским приложениям, которые мы отсканировали две недели назад.
Звучит как рутина. На практике - несколько вечеров в режиме «найди ответственного и договорись о деплое».
Что разворачивали
Картина по клиентам неоднородная. Условно три группы:
-
Spring Boot на embedded Tomcat, CI/CD в порядке. Обновление зависимости в pom.xml или build.gradle, прогон пайплайна, деплой. Минимум касания руками. Таких большинство - и именно с них начали в первую очередь. Некоторые сделали сами, нам оставалось только проверить версию в продакшене.
-
WAR-деплой на внешний Tomcat. Здесь сложнее: версия Spring зашита в артефакт, который может собираться отдельной командой или вообще сторонним вендором. Несколько приложений такого типа пришлось координировать напрямую с разработчиками клиента - не все из них были рады звонку в пятницу вечером с просьбой срочно пересобрать артефакт.
-
Легаси без активной разработки. Самая неудобная категория. Приложение работает, никто его особо не трогает, процесс сборки где-то задокументирован в вики трёхлетней давности. Тут пришлось восстанавливать контекст сборки, проверять что вообще есть в репозитории и договариваться о тестировании перед деплоем.
WAF-правила, которые поставили в первые дни после появления PoC, оставили на месте - пусть работают параллельно с патчингом. Не потому что не доверяем патчу, а потому что убирать их в разгар обновлений незачем.
Где реестр реально помог
После Log4Shell-аудита в январе мы настаивали на том, чтобы у клиентов появился хотя бы базовый реестр Java-компонентов: что запущено, на каком рантайме, какие ключевые фреймворки и версии. Тогда это выглядело как лишняя бюрократия на фоне усталости от декабрьского Log4Shell-марафона.
Spring4Shell показал разницу. Время от «вышел патч» до «мы знаем, кого и в каком порядке обновлять» сократилось с часов до минут. Не потому что мы стали умнее - просто список уже был, версии были проставлены, приоритеты очевидны.
Там, где реестра не было или он не обновлялся с января, пришлось сначала выяснять текущее состояние - и это съело время, которое в идеале должно было уходить на сам патчинг.
Один неприятный момент: пара приложений в реестре числилась с версией Spring 5.2.19 (уже закрытая), а в реальности на серверах ещё жила 5.2.18. Кто-то обновил запись в документе раньше, чем задеплоил фактически. Мелочь, но именно из-за таких мелочей финальную проверку делаем не по документу, а по живому процессу - mvn dependency:tree или прямой запрос к actuator/info, если он открыт.
Про Spring Boot 2.6.6 отдельно
Spring Boot 2.6.6 включает уже обновлённый Spring Framework 5.3.18, так что для большинства современных приложений достаточно поднять версию Boot - транзитивные зависимости подтянутся сами. Это снижает вероятность ошибки: не нужно отдельно следить за версией spring-webmvc и spring-beans, Boot управляет BOM.
Для тех, кто использует Spring Boot 2.5.x - там выпустили 2.5.12 с тем же патчем. Некоторые клиентские приложения ещё живут на 2.5, и переход сразу на 2.6 мы не рекомендовали без нормального тестирования - лучше минорное обновление в рамках той же ветки.
Итог на сегодня
По managed-клиентам обновление развёрнуто везде, где приложения попадают под условия уязвимости. Несколько WAR-деплоев с легаси-кодом - в процессе: ждём пересборки от разработчиков, контакт установлен, сроки согласованы.
WAF-правила снимем, когда убедимся что патч везде на продакшене - не раньше.
Если сравнивать с Log4Shell: тогда только обнаружение того, что вообще нужно обновить, заняло несколько дней. Сейчас - несколько минут на актуализацию реестра и расстановку приоритетов. Реестр - не серебряная пуля, но он окупился дважды за три месяца.
- Log4Shell: завершаем январский аудит и считаем хвосты · 7 января 2022