XZ Utils и доверие к мейнтейнеру: как мы пересмотрели политику обновлений
XZ Utils показал, что атака через long-term contributor - реальный вектор. Описываем, как пересмотрели политику обновлений для системных пакетов: задержка 72 часа и перекрёстная проверка.
XZ Utils инцидент обнажил проблему maintainer trust в Open Source: атака велась через долгосрочную имитацию участия в сообществе
После того как мы разобрали CVE-2024-3094 технически, у нас начался разговор другого рода - внутри команды и с несколькими клиентами. Не про версии xz и не про openssh. Про то, как вообще работает доверие к пакету и что нам с этим делать.
История Jia Tan - это не про дыру в коде. Это про дыру в процессе. Два года методичной работы, полезные патчи, репутация в списках рассылки - и в результате права на коммит в проект, на который завязана инфраструктура миллионов серверов. Автоматические проверки здесь ничего не дали бы: код был технически корректным вплоть до момента, когда он перестал им быть.
Что нас зацепило сильнее всего
Стандартная логика patch management выглядит так: вышла новая версия, проверили CVE, нет критичных - обновились. Мы сами так работали, и в целом это разумно. Но XZ Utils показал сценарий, где проблема приходит именно с новой версией, а не исправляется ею.
Злоумышленник получил доверие, выпустил релиз с закладкой - и этот релиз попал в дистрибутивы раньше, чем кто-то успел его внимательно посмотреть. Между тегом на GitHub и пакетом в Fedora Rawhide прошли дни, не месяцы. Никакой аномалии в CVE-фидах не было - потому что CVE ещё не существовало.
Вот это и есть проблема maintainer trust: ты обновляешься не потому что проверил, а потому что доверяешь репутации проекта и имени мейнтейнера. Обычно это работает. Иногда - нет.
Что мы поменяли
Мы не придумали универсальное решение - такого, скорее всего, не существует. Но скорректировали собственную политику обновлений для пакетов системного уровня.
Задержка 72 часа после релиза. Для пакетов, которые напрямую касаются системных вызовов, аутентификации, сетевого стека и базовых криптографических библиотек, мы больше не обновляемся в первые трое суток. За это время обычно успевает отработать более широкое сообщество: появляются первые разборы, репорты на reddit и HN, иногда - быстро найденные проблемы. Это не гарантия, но это фильтр.
Перекрёстная проверка по нескольким каналам. Перед обновлением системного пакета смотрим минимум на три источника: changelog от дистрибутива, upstream release notes и что-нибудь вроде обсуждения в профильных рассылках или треда на LWN. Если релиз прошёл тихо и нигде ничего нет - это нормально. Если есть разброс между тем, что написано в changelog, и тем, что обсуждают в рассылке - это повод притормозить.
Явный список пакетов под повышенным вниманием. Мы составили короткий перечень: libc, libssl/libcrypto, libsystemd, libssh, pam, sudo, openssh-server, ядро и его модули. Для них задержка и перекрёстная проверка обязательны. Для всего остального - прежний процесс с приоритетом по CVSS.
Просмотр истории новых контрибьюторов при нетривиальных изменениях. Это самое трудозатратное и применяем точечно. Если обновление небольшое и changelog понятен - не смотрим. Если в релизе есть изменения в логике аутентификации, инициализации или системных хуках - смотрим, кто это писал и когда этот человек появился в проекте.
Почему именно так, а не иначе
72 часа - это не магическое число. Это компромисс между оперативностью (настоящие 0-day важно закрыть быстро) и паузой для первичного «переваривания» релиза сообществом. Для критичных CVE у нас по-прежнему нет задержки - там действует отдельный регламент.
Перекрёстная проверка выглядит как лишняя работа - до первого инцидента, когда считаешь, сколько времени ушло на разбор. Мы сделали шаблон чеклиста - занимает минут пятнадцать на пакет при наличии привычки.
С историей контрибьюторов сложнее. Jia Tan работал в проекте два года - по любым меркам это «старый» участник. Значит, просто смотреть на дату первого коммита недостаточно. Важнее - паттерн изменений: когда человек вдруг начинает трогать чувствительные части кода, которых раньше не касался, это уже интереснее.
Где мы сейчас
Новая политика введена несколько дней назад - слишком мало, чтобы делать выводы. Пока она добавила аккуратности в работу с обновлениями и несколько раз заставила посмотреть на changelog внимательнее, чем обычно.
Задержка ни разу не создала проблем - ни один из пакетов за это время не потребовал срочного патча, который бы мы пропустили. Но это вопрос везения и объёма выборки.
Проверяем эту логику в рамках аудита инфраструктуры клиентов - смотрим, как у них устроены политики обновлений и есть ли вообще явный список критичных системных зависимостей. У большинства его нет, и XZ Utils - хороший повод этот разговор начать.