Атака на цепочку поставок Rust: вредонос в cargo build через крейт arrayref

Коротко о главном
20 августа 2026 года атакующие скомпрометировали учётную запись мейнтейнера и опубликовали вредоносные версии трёх популярных Rust-крейтов: arrayref 0.3.10 (245 млн загрузок за всё время, 403 зависимых пакета на crates.io), internment 0.8.7 и append-only-vec 0.1.9. Заражённые версии провисели в реестре от 86 до 107 минут и были удалены после обращения команды Nextron Systems в Rust Security Response Team. Вредоносный build-скрипт запускался при обычном cargo build — без вызова кода из самих крейтов. Доказательств реальной эксплуатации в продакшн-проектах пока нет.
Командам, использующим Rust в разработке, необходимо проверить локальные кэши ~/.cargo/registry/cache на наличие затронутых версий и зафиксировать arrayref не выше версии 0.3.9. Подробнее о том, как выстроить аудит кода и зависимостей в CI-пайплайне — в разделе услуг.
Как работала атака
Ключевым вектором стал тайпсквоттинг: атакующие зарегистрировали пакет proc-macro1 — намеренная имитация широко используемого proc-macro2, которая визуально почти неотличима. В заражённых версиях arrayref, internment и append-only-vec этот пакет добавлялся как зависимость. Его build-скрипт при каждой сборке:
- собирал адрес командного сервера из фрагментов base64, скрытых в коде;
- отключал проверку TLS-сертификатов, чтобы обойти HTTPS-контроль;
- подбирал платформо-зависимую полезную нагрузку (Unix, macOS или Windows);
- скачивал и запускал имплант, крадущий учётные данные браузеров и принимающий удалённые команды.
Критически важная деталь: вредоносный код срабатывал на этапе компиляции, а не во время выполнения программы. Достаточно было запустить cargo build или cargo check в проекте, разрешающем эти версии, — вызывать функции крейтов не требовалось. Дополнительно атакующие отозвали предыдущие версии arrayref (0.3.5–0.3.9), чтобы свежая вредоносная выглядела единственным «безопасным» вариантом для тех, кто ставит «последнюю стабильную».
Кто за этим стоит и что это значит
Специалисты Wiz выявили существенное пересечение инфраструктуры и техник этой атаки с кампаниями, которые атрибутируются Северной Корее (DPRK). Это соответствует публично задокументированному интересу северокорейских APT-групп к атакам на разработчиков: компрометация машин инженеров позволяет получить доступ к частным репозиториям, облачным токенам и учётным данным корпоративных сервисов.
Мейнтейнер arrayref — Эндрю Гэллант (Andrew Gallant), известный в сообществе как BurntSushi и автор популярной утилиты ripgrep. Команда Rust Security Response Team не считает его причастным: по всей видимости, были скомпрометированы его машина или учётные данные. Аккаунт заблокирован на crates.io, контакт с мейнтейнером установлен.
Инцидент демонстрирует новую фазу атак на цепочку поставок: злоумышленники целенаправленно выбирают высокодоверенных мейнтейнеров открытых проектов, а не просто пытаются подсунуть незнакомый пакет. Этот подход уже применялся в атаке на xz Utils (2024) и атаках на npm-пакеты TanStack и AsyncAPI в 2026 году.
Временная шкала инцидента
07:15 UTC 20 августа 2026 года — атакующие опубликовали вредоносные версии трёх крейтов. В то же время в Rust Security Response Team поступил первичный отчёт от Nextron Systems GmbH с указанием на вредоносный proc-macro1.
07:15–09:25 UTC — заражённые версии были доступны: arrayref 0.3.10 провисел 86 минут, internment 0.8.7 — 90 минут, append-only-vec 0.1.9 — 107 минут. За это время их могли скачать те, кто запустил cargo update или добавил свежую зависимость в открытое окно.
К 09:25 UTC — все три версии удалены с crates.io командой безопасности Rust. Аккаунт мейнтейнера arrayref заблокирован как мера предосторожности.
20–21 августа — Wiz опубликовал анализ с атрибуцией к DPRK-кампаниям. The Hacker News и официальный Rust Blog выпустили детальные технические разборы.
Что проверить прямо сейчас
Если ваша команда использует Rust, выполните следующие проверки независимо от того, есть ли arrayref в прямых зависимостях (он мог быть транзитивным через одну из 403 зависимых библиотек).
Проверить кэш Cargo: найдите файлы затронутых версий в локальном реестре. Команда для Unix/macOS:
find ~/.cargo/registry/cache -name "arrayref-0.3.10.crate" -o -name "internment-0.8.7.crate" -o -name "append-only-vec-0.1.9.crate"
Зафиксировать безопасные версии в Cargo.lock: arrayref не выше 0.3.9, internment — до 0.8.7, append-only-vec — до 0.1.9.
Проверить, были ли скомпрометированы учётные данные: если сборка выполнялась в промежутке 07:15–09:25 UTC 20 августа с обращением к затронутым версиям, проверьте браузерные keychain, облачные токены и токены CI/CD на предмет несанкционированного использования.
Обновить зависимости в CI: убедитесь, что пайплайн строит только от закреплённых хэшей из Cargo.lock и блокирует cargo update в production-ветках. Встроить автоматизированное тестирование безопасности зависимостей в CI помогает выявить подобные аномалии до деплоя.
Включить cargo-audit или cargo-deny: эти инструменты умеют проверять зависимости против баз уязвимостей RustSec и помечать отозванные версии.
Что это значит для команд разработки
Атака на arrayref — не изолированный инцидент, а демонстрация зрелости атак на цепочку поставок open-source. Три ключевых вывода для технических команд и CTO.
Во-первых, компиляция теперь является поверхностью атаки. Build-скрипты в экосистеме Rust (и аналоги в npm, PyPI, Maven) выполняются с правами текущего пользователя. Любой вредоносный крейт в дереве зависимостей — прямой или транзитивный — запускается прежде, чем вы увидите результат сборки. Это означает, что периметр защиты должен охватывать не только код, который вы пишете, но и код, который вы потребляете.
Во-вторых, высокая репутация мейнтейнера больше не является гарантией. BurntSushi — один из наиболее уважаемых авторов в экосистеме Rust. Атакующие целенаправленно выбирают именно таких людей: их крейты встроены в тысячи проектов по умолчанию, а пакет-менеджеры доверяют им без дополнительной верификации.
В-третьих, окно реагирования становится меньше. 86 минут — достаточный срок, чтобы CI/CD тысяч проектов успел скачать и скомпилировать отравленный пакет, особенно в командах, которые запускают сборки по таймеру или при каждом push. Защита строится не на скорости реакции, а на превентивных мерах: закрепление версий в lock-файлах, запрет автообновления зависимостей в продакшн-ветках и автоматический аудит зависимостей в каждом PR.
Часто задаваемые вопросы
Затронут ли я, если не использую arrayref напрямую? Возможно. Крейт arrayref используют 403 пакета на crates.io. Если хотя бы один из ваших транзитивных зависимостей тянул его в промежутке 07:15–09:25 UTC 20 августа, ваша сборка потенциально была под угрозой. Проверьте Cargo.lock на наличие arrayref 0.3.10, internment 0.8.7 или append-only-vec 0.1.9.
Версии удалены — я в безопасности при следующей сборке? Если вы запустите чистую сборку от актуального Cargo.lock без проблемных версий — да. Если у вас в кэше остались .crate-файлы заражённых версий, Cargo может использовать их повторно. Очистите кэш командой выше.
Этот тип атаки специфичен для Rust? Нет. Похожие атаки через build-скрипты происходят в npm (postinstall), PyPI (setup.py/pyproject.toml), Maven и других экосистемах. Rust оказался в фокусе из-за высокой популярности arrayref и доверия к BurntSushi как мейнтейнеру.
Как снизить риск в будущем? Закрепляйте версии в lock-файлах и не разрешайте автоматических обновлений в продакшн-пайплайнах, используйте cargo-audit или cargo-deny в CI, настройте алерты на появление новых зависимостей в pull-requests и рассмотрите зеркалирование критичных крейтов во внутреннем реестре.
Источники
Rust Blog — Supply chain attack on arrayref, 20 августа 2026 года (официальный первоисточник от Rust Security Response Team).
The Hacker News — Rust Supply Chain Attack Puts Build-Time Malware in Crates with 245 Million Downloads, 20 августа 2026 года.
Wiz Blog — Rust Supply Chain Attack on arrayref: Significant Overlap with DPRK Campaigns, 2026 год.
Ваш стек использует Rust или npm-зависимости?
Проведём аудит зависимостей и CI-пайплайна — выявим транзитивные риски до того, как это сделает атакующий.