У Cargo нашли ошибку на границе кеша, особенно опасную за пределами crates.io. Rust Security Response Team сообщает, что CVE-2026-5223 позволяет вредоносному tarball с crate из стороннего реестра перезаписать кешированный исходный код другого crate из того же реестра, злоупотребив symlink при распаковке.
Условие узкое, но не безобидное. Системы сборки доверяют локальному кешу исходников Cargo. Если один crate может менять кешированный код другого, граница доверия к реестру оказывается слабее, чем ожидают разработчики.
Пользователи crates.io — не главная группа риска. В advisory Rust сказано, что crates.io запрещает загрузку crate с symlink, поэтому опасный вход блокируется на уровне реестра. Риск касается сторонних реестров, которые разрешают symlink внутри tarball с crate, зеркалируют такие архивы или не отбрасывают их.
Что произошло#
Cargo скачивает tarball с crate и распаковывает исходники в локальный кеш внутри домашнего каталога Cargo. Этот кеш затем повторно используется в следующих сборках — обычное поведение для менеджера пакетов. Так меньше повторных загрузок, а сборки идут быстрее.
В Cargo уже были защиты, которые должны были не дать файлам распаковаться за пределы собственного каталога кеша crate. Сообщенная Rust Security Response Team проблема была точнее: специально подготовленный tarball мог использовать symlink так, чтобы записывать файлы на один уровень ниже собственного каталога кеша crate.
Из-за структуры путей кеша реестров в Cargo такой выход на один уровень мог позволить вредоносному crate перезаписать файлы, принадлежащие другому crate из того же реестра. Advisory описывает это как подмену исходного кода внутри кеша, а не как произвольную запись файлов по всей системе.
Это важное различие. Баг не описывают как прямой RCE против каждого Rust-разработчика. Риск тоньше: сборка может скомпилировать код, который не совпадает с исходниками crate, которые, как думал разработчик, лежали в кеше Cargo.
Кто под риском#
Advisory говорит прямо: серьезность относится к пользователям сторонних реестров. Затронуты все версии Cargo, поставлявшиеся до Rust 1.96.0, но возможность эксплуатации зависит от того, может ли реестр отдавать tarball с crate, содержащий symlink.
У пользователей, которые получают зависимости только с crates.io, уже есть сильная защита. Crates.io не разрешает загружать crate с symlink. По словам Rust team, это значит, что уязвимое поведение Cargo недостижимо через обычную публикацию пакета на crates.io.
Пользователям приватных и сторонних реестров стоит относиться к проблеме иначе. Внутренние реестры часто нужны организациям для контроля происхождения пакетов, доступности или политик. CVE-2026-5223 бьет прямо по этой модели доверия: реестр может считаться доверенным, но один вредоносный или скомпрометированный пакет внутри него способен повлиять на кешированный код другого пакета на машине разработчика или build worker.
Advisory также отмечает, что Cargo никогда не добавлял symlink при выполнении cargo package. Это снижает вероятность случайного риска. Обычный пакет, созданный через стандартный процесс упаковки Cargo, не должен содержать symlink этим путем. Более актуальные сценарии — вредоносные tarball, кастомные процессы публикации, импорт в реестр или зеркала, которые сохраняют неожидимое содержимое архивов.
Исправление в Rust 1.96.0#
Rust 1.96.0, выпуск которого запланирован на 28 мая 2026 года, обновляет Cargo: теперь он будет отвергать распаковку symlink из tarball с crate. Правило действует независимо от источника: crates.io, приватные реестры или другие сторонние реестры.
Это правильное исправление. Оно не требует, чтобы каждый реестр безошибочно применял одну и ту же политику. Проверка переносится в клиент: Cargo может отказаться от рискованной структуры архива до изменения состояния кеша.
Компромисс есть, но выглядит небольшим. Поскольку cargo package не добавлял symlink, легитимные crate, созданные обычными процессами Cargo, не должны зависеть от записей symlink внутри опубликованных tarball. Операторам реестров все равно стоит проверить кастомную упаковку перед rollout, но advisory описывает ожидаемый эффект как минимальный.
Что проверить операторам реестров#
Основная практическая работа ложится на команды, которые используют приватные Rust-реестры, альтернативные реестры или внутренние зеркала.
Начните с политики реестра. Если ПО реестра умеет отклонять symlink в загружаемых tarball с crate — включите эту проверку. Если не умеет, добавьте валидацию при загрузке или при приеме пакета: нужно просматривать записи архива до того, как пакет будет принят.
Затем проверьте уже существующее содержимое реестра на symlink. Advisory рекомендует это пользователям, которые не могут обновиться сразу. В проверку стоит включить пакеты, импортированные из других источников, старые внутренние crate и все, что создавалось кастомным пайплайном публикации, а не через cargo package.
Сборочную инфраструктуру стоит рассмотреть отдельно. Общие CI workers и долго живущие сборочные машины чувствительнее к отравлению кеша, чем одноразовые чистые окружения. Если worker переиспользует состояние кеша Cargo между проектами, вредоносный crate из того же реестра получает больше шансов повлиять на последующие сборки.
Консервативный подход — совместить обновление Cargo с гигиеной кеша: очистить кеши реестров Cargo на общих билдерах после обновления, особенно там, где используются сторонние реестры. Advisory не говорит, что очистка кеша обязательна, но это разумный операционный шаг, если есть опасение, что кеш уже мог быть заполнен из недоверенных tarball.
Что не стоит преувеличивать#
Advisory не говорит, что crates.io был скомпрометирован. Там сказано, что crates.io запрещает symlink в crate, и это защищает пользователей crates.io от опасной формы архива.
Также не утверждается, что каждая сборка Cargo до Rust 1.96.0 небезопасна. Уязвимый код есть в Cargo, но реальный риск зависит от того, отдает ли реестр вредоносный tarball с crate, содержащий symlink.
Это не описывается и как общий выход за пределы файловой системы. Защиты Cargo от распаковки за пределы каталога кеша crate не отсутствовали полностью. Сообщенный обход позволял распаковку на один уровень ниже собственного каталога кеша crate, что стало значимым из-за того, что кеши соседних crate находятся рядом.
Даже в такой узкой трактовке проблема серьезная. Кеши менеджера пакетов — часть цепочки доверия сборки. Если вредоносный пакет может переписать кешированный исходный код другого пакета, это не косметический сбой. Это ломает предположение, что идентичность зависимости, источник в реестре и локальное содержимое исходников аккуратно совпадают.
Практический вывод#
Если вы используете Rust только с crates.io, обновитесь после выхода Rust 1.96.0, но этот advisory адресован не в первую очередь вам.
Если вы используете сторонние реестры, считайте обновление приоритетом. Обновите Cargo через Rust 1.96.0 или более новую версию, когда она станет доступна. До этого проверьте tarball в реестре на symlink и по возможности настройте реестр так, чтобы он их отклонял.
Главная проверка простая: может ли tarball с crate в вашем реестре сегодня содержать symlink? Если ответ «да» или никто не знает, этот advisory — повод закрыть пробел.