Обработка жёстких ссылок в tarfile из CPython обходит фильтр распаковки и записывает отклонённые файлы

Python

В стандартной библиотеке CPython обнаружили уязвимость CVE-2026-87910. Ошибка находится в модуле tarfile, который распаковывает архивы формата tar. Оценка по шкале CVSS 4.0 составила 5.7 балла, это средний уровень. Уязвимы все выпуски CPython до 3.15.0. При определённых условиях программа записывает на диск элементы архива, которые пользовательский фильтр распаковки отклонил.

Уязвимость CVE-2026-87910

Модуль tarfile входит в стандартную поставку Python, поэтому его применяют почти везде: от утилит командной строки до систем сборки и сервисов доставки пакетов. У модуля есть механизм фильтров. Фильтр - это функция, которая решает, что из архива распаковывать, а что пропустить. Возврат None означает отказ: элемент считается небезопасным и на диск попадать не должен. Такой барьер задумывался как защита от архивов, которые пишут данные за пределами каталога распаковки или подменяют файлы через ссылки.

Сбой проявляется на стыке ссылок и фильтров. Когда tarfile встречает ссылку на системе, где ссылки не поддерживаются, обычный сценарий не срабатывает. Модуль отступает к резервному варианту и распаковывает элемент из архива как обычный файл. В этом режиме фильтр вызывается дважды. Первый вызов относится к самому элементу, второй - к расположению ссылки. Возвращаемое значение одного из вызовов код игнорирует. Бюллетень описывает правильное поведение так: элемент нужно пропускать, если хотя бы один вызов вернул None. Сейчас отказ фильтра в одном из случаев просто теряется.

Последствия касаются целостности данных. Классификаторы отнесли проблему к CWE-22, обход путей, и CWE-59, следование по ссылке. Оба класса описывают одну и ту же угрозу: файл оказывается там, где его быть не должно. Пользователь или приложение доверяют фильтру и рассчитывают, что отклонённый элемент останется внутри архива. Злоумышленник собирает архив так, чтобы нужный файл отсекался по одному вызову, но всё равно проходил по второму. В результате содержимое архива попадает на диск вопреки правилам, которые задал сам пользователь.

Вектор атаки в записи CVSS сетевой, то есть архив может прийти по сети. Уязвимость требует активного участия пользователя и определённых условий в среде. Права нужны низкие. Влияние на целостность оценено как высокое, а на конфиденциальность и доступность - как нулевое. Значит, злоумышленник не читает чужие данные и не останавливает сервисы. Он размещает или подменяет файлы там, где их не ждут. Для этого жертве достаточно распаковать подготовленный архив в уязвимой среде.

Кого это касается в первую очередь. Архивы tar постоянно ходят через системы непрерывной интеграции, репозитории пакетов, каналы обмена резервными копиями и обычную почту. Риск выше там, где распаковывают недоверенные архивы и полагаются на фильтр как на единственную защиту. Отдельная деталь: резервный режим включается на системах без поддержки ссылок, поэтому один и тот же архив ведёт себя по-разному на разных платформах. Сведения об эксплуатации в реальных атаках в бюллетене не приводятся.

Исправление готово. Фонд разработки Python выпустил бюллетень безопасности 11 сентября 2026 года и патч к основной ветке. Уязвимость закрыта в CPython 3.15.0: код теперь пропускает элемент, если любой из двух вызовов фильтра вернул None. Тем, кто работает на более ранних выпусках, стоит обновиться до свежей версии или наложить правку вручную. Если обновление откладывается, снизить риск помогает распаковка архивов в изолированной среде и проверка содержимого до запуска. Ещё один вариант - не полагаться на один фильтр, а дополнительно сверять список файлов внутри архива.

В том же выпуске бюллетеня упомянута CVE-2026-15310, связанная с исчерпанием памяти. Описание по ней в исходном сообщении не раскрыто, детали приведены в записи CVE. История с tarfile показывает общую слабость защитных механизмов распаковки. Фильтры появились именно для того, чтобы отделять безопасные архивы от опасных. Ошибка в порядке вызова функций ломает эту логику без всякого вредоносного кода со стороны атакующего. Обновление до 3.15.0 закрывает вопрос, а до тех пор риск остаётся управляемым, поскольку сценарий требует, чтобы жертва сама распаковала чужой архив.

Ссылки

Комментарии: 0