
Большинство советов по безопасности для пользователей крипты сосредоточено на видимых поверхностях: ваша seed-фраза, ссылки, на которые вы нажимаете, сайты, где вы входите. Это важно. Но под всем этим лежит более тихий риск — само программное обеспечение и всё, из чего оно собрано. Кошелёк можно написать безупречно и всё равно поставить с ним бэкдор, потому что современные приложения собираются из сотен сторонних строительных блоков и из конвейера сборки, превращающего исходный код в бинарник, который вы устанавливаете. Скомпрометируйте любое звено этой цепочки — и вы скомпрометируете каждого пользователя ниже по потоку.
Это и есть цепочка поставок ПО, и атакующие усвоили, что она — одна из самых рычажных целей в крипте. Эта статья объясняет, что такое атака на цепочку поставок на самом деле, почему кошельки — столь привлекательные цели, какие средства защиты работают на практике и что дают детерминированные сборки, включая то, как всё это применяет SSP.
Что такое атака на цепочку поставок
Атака на цепочку поставок не взламывает приложение напрямую. Вместо этого она компрометирует то, чему приложение доверяет: подключаемую зависимость, учётную запись мейнтейнера или конвейер сборки, собирающий итоговый артефакт. Вредоносный код попадает через легитимное обновление, подписанное и доставленное обычными каналами, поэтому выглядит ровно как то ПО, которое вы собирались установить.
В этой опосредованности и весь смысл. Атака на одну широко используемую библиотеку — или один сервер сборки — может достичь тысяч нижестоящих проектов и миллионов пользователей разом. Для криптокошелька выигрыш прямой: код, работающий внутри вашего кошелька, уже имеет доступ к решающему моменту — когда транзакция подписывается, а адреса отображаются. Одна подменённая зависимость может заменить адрес назначения или вывести ключевой материал, ни разу не коснувшись вас через фишинг или слабую гигиену seed-фразы. Вот почему этот класс атак заслуживает места в вашей ментальной модели.
Два случая, которые бьют близко
Два реальных инцидента показывают, как это разворачивается, — один нацеленный прямо на крипту, другой едва не задевший весь интернет.
event-stream и кошелёк Copay
В 2018 году популярный npm-пакет event-stream передали новому мейнтейнеру-добровольцу, предложившему помощь. Это была рутинная, на вид благонамеренная передача — из тех, что постоянно случаются в опенсорсе. Затем новый мейнтейнер добавил свежую зависимость, flatmap-stream, содержавшую обфусцированный вредоносный код.
Полезная нагрузка была необычно прицельной. Вместо того чтобы срабатывать у всех, она активировалась только внутри конкретного нижестоящего проекта: биткойн-кошелька Copay. Там она была сделана так, чтобы красть seed-материал и средства пользователей именно этого приложения. Большинство разработчиков, подключивших event-stream, так и не пострадали — код точно знал, какую жертву ищет.
Это каноническое напоминание: «я установил всего одну маленькую библиотеку» — никогда не вся история. Вы установили и всё то, чему эта библиотека доверяет.
Бэкдор в XZ Utils
Инцидент с XZ Utils 2024 года (CVE-2024-3094) был ещё терпеливее. XZ Utils — это библиотека сжатия, незаметно присутствующая в большинстве систем Linux. На протяжении лет атакующий нарабатывал доверие как полезный контрибьютор, постепенно получал обязанности мейнтейнера, а затем внедрил бэкдор, рассчитанный на вмешательство в OpenSSH — программу, защищающую удалённые входы на серверы повсюду.
Его поймали почти случайно — благодаря инженеру, заметившему задержку в доли секунды. Если бы он разошёлся широко, он мог бы открыть удалённый доступ к бесчисленным машинам.
Урок для крипты отрезвляющий: атака использовала не хитрый баг, а саму модель доверия опенсорса, разыграв многолетнюю партию социальной инженерии, чтобы стать человеком, на которого все полагались.
Защиты, которые действительно работают
Ни один отдельный механизм не останавливает атаки на цепочку поставок. Работает стек из них, и каждый сужает возможности атакующего:
- Зафиксированные зависимости и lock-файлы. Фиксация точных версий и хранение lock-файла означает, что сборка не может молча подтянуть более новый, подменённый релиз. Обновления становятся осознанными, проверяемыми событиями, а не автоматическими.
- Минимум зависимостей. Каждый добавленный пакет — это сторона, которой вы доверяете. Меньше зависимостей — меньше поверхность атаки и меньше мейнтейнеров, которых можно скомпрометировать.
- Песочница для зависимостей. Инструменты вроде LavaMoat ограничивают то, что каждый пакет может делать во время выполнения, так что скомпрометированная зависимость не может свободно достучаться до сети или чувствительных API.
- Подпись кода. Подписанные релизы позволяют пользователям проверить, что бинарник пришёл от настоящего издателя и не был изменён в пути.
- Сторонние аудиты. Независимые охранные фирмы изучают код и зависимости враждебным взглядом, замечая то, что внутренние команды считают нормой.
- Воспроизводимые, детерминированные сборки. Сильнейшая структурная защита и та, которую стоит понять в деталях.
Детерминированные сборки, объяснение
Обычно двукратная сборка из одного и того же исходника может дать два слегка разных бинарника — туда просачиваются временные метки, порядок файлов и детали сборочной машины. Эта изменчивость — проблема, ведь она означает, что вы не отличите безобидное различие от вредоносного.
Детерминированная (или воспроизводимая) сборка устраняет эту изменчивость. При одном и том же исходном коде кто угодно, где угодно, на любой машине производит побайтово идентичный артефакт. Следствие мощное: независимые люди могут пересобрать кошелёк из его открытого исходника и подтвердить, что скачанный вами бинарник совпадает, бит в бит, с тем, что производит исходник. Если атакующий подделал конвейер сборки или подсунул что-то позже, хеши не совпадут, и подделка станет сразу заметна.
Это переворачивает модель доверия. Вам больше не нужно верить издателю на слово; проверка становится тем, что всё сообщество может выполнить и перепроверить. Проект Reproducible Builds документирует эту практику по всей экосистеме, а фреймворки вроде SLSA задают уровни гарантий целостности сборки, которых вы можете требовать от проекта.
Как это применяет SSP
SSP рассматривает конвейер сборки как часть своей модели угроз, а не как нечто второстепенное. Кошелёк поставляется с детерминированной сборкой на основе Dockerfile: одна и та же определённая Docker среда каждый раз производит один и тот же артефакт, так что опубликованный релиз можно пересобрать из открытого исходника и сверить, бит в бит, с тем, что вы скачали. SSP также прошёл независимые проверки безопасности от Halborn, чьи аудиты изучают и код, и зависимости, на которые он опирается.
Есть ещё один слой, специфичный для того, как устроен SSP, и здесь он важен. SSP — это кошелёк с мультиподписью 2 из 2: каждая транзакция требует независимого одобрения вторым ключом, SSP Key, на отдельном устройстве. Будьте точны в том, что это даёт, а что нет. Детерминированные сборки и аудиты снижают шанс, что подделанная сборка вообще будет поставлена; это передовая линия. Но даже в худшем случае — если сборка как-то проскочила — второй ключ остаётся отдельной поверхностью одобрения, которая всё равно должна подписать каждую транзакцию.
Это не волшебный щит, и он не делает скомпрометированную сборку приемлемой. Он просто означает, что один подделанный компонент на одном устройстве сам по себе не двигает ваши средства. Эшелонированная защита — вот в чём суть.
Что вы можете проверить сами
Чтобы извлечь пользу из всего этого, не нужно быть инженером по безопасности. Несколько привычек дают многое:
- Скачивайте только из официальных источников. Берите кошелёк с его официального сайта или из магазина, никогда — по ссылке в сообщении или из поискового объявления. Это та же дисциплина, что описана в гигиене браузерных расширений.
- Предпочитайте проекты, публикующие детерминированные сборки и аудиты. Проект, позволяющий сообществу проверять свои релизы — и оплачивающий независимую проверку, — говорит вам кое-что о том, как он мыслит.
- Проверяйте подписи и хеши, когда они предложены. Если релиз поставляется с подписью или контрольной суммой, потратьте минуту на проверку. Воспроизводимые сборки защищают вас, только если кто-то действительно делает сверку.
- Держите общий opsec в тонусе. Защита цепочки поставок встроена в более широкую картину; регулярно проходите свой чек-лист opsec, чтобы ни один слой не нёс весь вес.
Ничто из этого не требует доверия к одной стороне. Именно этого свойства вы и хотите от ПО для самостоятельного хранения.
Двигайтесь дальше
Кошелёк настолько надёжен, насколько надёжна цепочка, которая его собрала. Хорошая новость в том, что это одна из немногих проблем безопасности с чистым, структурным ответом: детерминированные сборки плюс независимые аудиты превращают «доверьтесь нам» в «проверьте сами».
Продолжайте выстраивать защиту с осведомлённостью о фишинге, лучшими практиками seed-фразы, гигиеной браузерных расширений и регулярным чек-листом opsec. Каждая закрывает одну дверь; вместе они и есть то, как на самом деле выглядит безопасность самостоятельного хранения.


