Мы читаем реальные публичные инциденты не как повторный прогон новостей, а через призму «как бы вы от этого защитились». Эта статья основана на публичных материалах (официальный post-mortem, CISA, анализ от поставщиков безопасности), ссылки приведены в конце.
- Цель
- Codecov (инструмент покрытия кода) и CI его клиентов
- Раскрытие
- 15 апреля 2021 (изменение с 31 января / обнаружено 1 апреля)
- Класс
- атака на цепочку поставок (изменение доверенного артефакта на стороне поставщика) + кража секретов CI
- Масштаб
- многие клиенты Codecov (до ~29 000). Downstream-удары по HashiCorp, Twilio, Rapid7
- Первопричина
- CI запускал загруженный артефакт без проверки + работа поставщика с ключами + чрезмерно открытые секреты CI
- Основные меры
- проверять загружаемые артефакты, минимальные привилегии секретов CI, ротация, мониторинг исходящего трафика
Что произошло (простыми словами)
Многие команды загружают и запускают внешние инструменты как есть в своём CI, например через curl … | bash. Bash Uploader от Codecov был таким скриптом.
Злоумышленник использовал слабость в системе распространения Codecov, чтобы переписать сам распространяемый скрипт, так что при запуске в CI он отправлял переменные той среды (секреты) на внешний сервер. С точки зрения клиента, он просто вызвал доверенный инструмент как всегда. Поскольку ни строчки вашего кода не изменилось, почти нет сигнала о чём-то неладном.
Примерно через два месяца клиент сравнил контрольную сумму скрипта (SHA256) с официальным значением и нашёл несовпадение. Так изменение и обнаружили. Среди утёкшего могли быть облачные ключи, deploy-ключи, API-ключи и токены, и отсюда атака выстроилась в цепочку до downstream-утечек в таких компаниях, как HashiCorp и Twilio.
Ваш собственный код не меняется, поэтому это трудно заметить
Атаки на цепочку поставок нацелены не на написанный вами код, а на то, чему вы доверяете и что подтягиваете. Поэтому ревью кода и логи редко их ловят. Команды склонны не проверять инструменты, которым доверяют, и именно этой слабостью пользуются атакующие.
Этапы атаки и как остановить каждый из них
Важно, что это была цепочка из четырёх шагов, и на каждом шаге было место для остановки. Читайте это как «где её можно было остановить», а не как рецепт атаки.
① Запуск доверенного инструмента через curl | bash (содержимое не проверено)
⊘ остановка: закрепление версии + проверка контрольной суммы загружаемого артефакта / вендоринг
② Артефакт подменён в источнике (upstream)
Ваш код не трогали, поэтому заметить нельзя.
⊘ остановка: сравнение с заведомо корректным хешем; использование закреплённой версии
③ Переменные окружения CI (секреты, ключи, токены) отправлены наружу
⊘ остановка: минимальные привилегии, посекретные секреты CI (не передавать всё окружение)
④ Украденные ключи выстраиваются в цепочку к продакшену и другим сервисам
⊘ остановка: регулярная ротация ключей + мониторинг исходящего (egress) трафика
Хронология (по раскрытым данным)
2021-01-31
Начинается изменение Bash Uploader (далее с перерывами).2021-03–
Секреты неделями утекают из CI клиентов незамеченными.2021-04-01
Клиент находит несовпадение контрольной суммы и сообщает об этом.2021-04-15
Codecov раскрывает информацию публично; советует клиентам ротировать все секреты.2021-04–
Проявляется downstream-влияние в HashiCorp, Twilio, Rapid7. Codecov позже выводит Bash Uploader из эксплуатации.
Первопричина: больше чем одна ошибка
Списать всё на «вина Codecov» — и это повторится. На стороне клиента тоже не хватало нескольких защит.
Как было (на тот момент)
- CI запускал загруженный артефакт без проверки (доверяя
curl | bash) - Секреты CI чрезмерно открыты (каждый шаг видит каждую переменную окружения)
- Секреты редко ротировались (украденные ключи долго остаются действительными)
- Исходящий трафик CI без мониторинга
Как должно быть (профилактика)
- Закрепление версии + проверка контрольной суммы загружаемых артефактов или вендоринг
- Передавать секреты CI с минимальными привилегиями, только тем шагам, которым они нужны
- Ротировать секреты регулярно (короткий срок жизни даже при утечке)
- Мониторить исходящий трафик CI и обнаруживать отправки на неизвестные адреса назначения
Проверяйте даже инструменты, которым доверяете
Атаки на цепочку поставок нацелены на то, чему вы доверяете и что подтягиваете — библиотеки-зависимости, инструменты CI, сборочные образы. Случай XZ Utils имел ту же форму. Минимизируйте доверие и проверяйте целостность того, что подтягиваете, машинно.
Как предотвратить это в вашей среде
Исправления в порядке приоритета, работающие в любом масштабе. Один раз перечислите, чему доверяет и что запускает ваш CI, — и вы увидите, где это касается вас.
Проверяйте загружаемые артефакты (не доверяйте curl|bash вслепую)
Если CI подтягивает внешний скрипт или бинарник, требуйте закреплённую версию (тег/коммит) + проверку контрольной суммы (SHA256). Где возможно, вендорьте его в собственный репозиторий. Эту утечку поймала именно такая проверка.
Ограничьте секреты CI до минимальных привилегий
Не передавайте каждую переменную окружения каждому шагу. Передавайте только нужный секрет нужной задаче/шагу. Используйте короткоживущие токены (например, OIDC), чтобы сократить долгоживущие ключи в покое.
Регулярно ротируйте секреты
В случае кражи короткий срок жизни ограничивает ущерб. Сделайте ротацию рутиной, и ротируйте немедленно при сообщении об инциденте в цепочке поставок.
Мониторьте исходящий трафик CI (egress)
Имейте возможность обнаруживать отправки на неизвестные адреса назначения из CI. Даже если изменённый инструмент не поймали при загрузке, держите слой, замечающий эксфильтрацию.
Позиция этого сайта: минимизировать доверие, проверять
Этот сайт проектирует приём зависимостей и сборок так, чтобы он был машинно проверяемым. Codecov и XZ Utils показывают одно и то же: «мы этому доверяем» склонно становиться «мы это не проверяем», и атаки на цепочку поставок пользуются именно этим. Сокращайте доверие и механически подтверждайте целостность того, что подтягиваете.
Источники (публичные материалы)
Факты здесь основаны на следующей публичной информации, с фокусом на уроках защиты — а не на шагах воспроизведения или изменённом коде.
- Codecov, "Post-Mortem / Root Cause Analysis (April 2021)" — about.codecov.io
- Codecov, "Bash Uploader Security Update" — about.codecov.io
- CISA, "Codecov Releases New Detections for Supply Chain Compromise" (2021) — cisa.gov
- Rapid7, "Analysis of the Codecov Supply Chain Compromise" (2021) — rapid7.com
Читать дальше
- История: Бэкдор XZ Utils — атака на само доверие
- Глоссарий: Что такое .env (где собираются секреты)
- Защита: Машинно мониторьте свои зависимости
- Инцидент: Equifax — запущенный известный CVE · Capital One — SSRF