Простой ZIP-архив может успешно пройти проверку как PDF, а затем заменить рабочий скрипт на сервере. Разработчики библиотеки zip для языка Rust раскрыли уязвимость CVE-2026-115905, которая позволяет подменять имена файлов между проверкой и распаковкой. Опасность возникает в сервисах, автоматически принимающих и извлекающих архивы пользователей.
Причина кроется в устройстве формата ZIP. Имя каждого файла хранится дважды, в локальном заголовке перед содержимым и в центральном каталоге в конце архива. Обычно записи совпадают, но специально подготовленный ZIP может содержать разные имена. Два способа чтения в zip доверяют разным частям архива и не сверяют сведения между собой.
Компонент ZipArchive обращается к центральному каталогу и видит файл doc_report.pdf. Потоковый распаковщик ZipStreamReader читает локальный заголовок и находит уже cron_worker.sh. Если защитный шлюз проверяет имена файлов первым способом, а сервер извлекает содержимое вторым, разрешённый архив приводит к перезаписи системного скрипта.
Разработчики показали механизм в автоматическом тесте. Имитация защитного шлюза пропустила ZIP, поскольку обнаружила только PDF, после чего распаковщик перезаписал существующий cron_worker.sh текстом команд атакующего. Проверка подтвердила изменение содержимого файла. Сам тест не запускал подложенный скрипт и не доказывал фактический захват сервера.
При определённой конфигурации последствия не ограничиваются потерей файла. Если служба позже запустит заменённый скрипт, злоумышленник сможет добиться выполнения команд с правами соответствующего процесса. Перезапись необходимых для работы компонентов также грозит сбоем сервиса. Для атаки нужен путь загрузки чужого ZIP и его автоматическая распаковка.
Уязвимыми признаны версии zip вплоть до 9.0.4, а проблеме присвоили критические 10 баллов по CVSS 4.0. Похожая идея расхождения между содержимым архива и результатом проверки лежит в основе техники Zombie ZIP, позволяющей скрывать вредоносные файлы от ряда анализаторов. Однако механизм новой уязвимости связан именно с разными именами в двух заголовках.
Разработчики обозначили версию 9.0.5 как исправленную, но контроль совпадения заголовков в ZipStreamReader по умолчанию отключён. Проверку нужно активировать отдельно через enforce_header_consistency(true). В версии 9.0.5 распаковка вдобавок записывала файлы до окончания сравнения, поэтому ошибка могла обнаружиться уже после перезаписи.
В более новой версии 9.1.3 разработчики добавили временный каталог для распаковки при активной проверке. Файлы перемещаются на постоянное место только после успешного сравнения заголовков. Контроль по-прежнему выключен по умолчанию, поэтому одного обновления зависимости недостаточно. Приложениям требуется явно включать защищённый режим.
