Инциденты и уязвимости

Утечка Codecov (2021) — когда инструмент CI был изменён и утекли секреты

В 2021 году Bash Uploader от Codecov изменили у поставщика, и ~2 месяца он сливал секреты CI клиентов. Защита: проверка артефактов и ротация секретов.

Опубликовано 2026-06-07 Обновлено 2026-10-05 7 мин чтения
На этой странице

Мы читаем реальные публичные инциденты не как повторный прогон новостей, а через призму «как бы вы от этого защитились». Эта статья основана на публичных материалах (официальный post-mortem, CISA, анализ от поставщиков безопасности), ссылки приведены в конце.

~2 месяца
без обнаружения
~29 000
потенциально затронутых клиентов
проверка SHA
единственное обнаружение
downstream
HashiCorp/Twilio и др.
Досье инцидента
Цель
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) трафика

Каждый шаг можно было остановить: проверяйте то, что подтягиваете, ограничивайте секреты, ротируйте их и мониторьте исходящий трафик.

Хронология (по раскрытым данным)

  1. 2021-01-31

    Начинается изменение Bash Uploader (далее с перерывами).
  2. 2021-03–

    Секреты неделями утекают из CI клиентов незамеченными.
  3. 2021-04-01

    Клиент находит несовпадение контрольной суммы и сообщает об этом.
  4. 2021-04-15

    Codecov раскрывает информацию публично; советует клиентам ротировать все секреты.
  5. 2021-04–

    Проявляется downstream-влияние в HashiCorp, Twilio, Rapid7. Codecov позже выводит Bash Uploader из эксплуатации.

Первопричина: больше чем одна ошибка

Списать всё на «вина Codecov» — и это повторится. На стороне клиента тоже не хватало нескольких защит.

Как было (на тот момент)

  • CI запускал загруженный артефакт без проверки (доверяя curl | bash)
  • Секреты CI чрезмерно открыты (каждый шаг видит каждую переменную окружения)
  • Секреты редко ротировались (украденные ключи долго остаются действительными)
  • Исходящий трафик CI без мониторинга

Как должно быть (профилактика)

  • Закрепление версии + проверка контрольной суммы загружаемых артефактов или вендоринг
  • Передавать секреты CI с минимальными привилегиями, только тем шагам, которым они нужны
  • Ротировать секреты регулярно (короткий срок жизни даже при утечке)
  • Мониторить исходящий трафик CI и обнаруживать отправки на неизвестные адреса назначения

Проверяйте даже инструменты, которым доверяете

Атаки на цепочку поставок нацелены на то, чему вы доверяете и что подтягиваете — библиотеки-зависимости, инструменты CI, сборочные образы. Случай XZ Utils имел ту же форму. Минимизируйте доверие и проверяйте целостность того, что подтягиваете, машинно.

Как предотвратить это в вашей среде

Исправления в порядке приоритета, работающие в любом масштабе. Один раз перечислите, чему доверяет и что запускает ваш CI, — и вы увидите, где это касается вас.

1

Проверяйте загружаемые артефакты (не доверяйте curl|bash вслепую)

Если CI подтягивает внешний скрипт или бинарник, требуйте закреплённую версию (тег/коммит) + проверку контрольной суммы (SHA256). Где возможно, вендорьте его в собственный репозиторий. Эту утечку поймала именно такая проверка.

2

Ограничьте секреты CI до минимальных привилегий

Не передавайте каждую переменную окружения каждому шагу. Передавайте только нужный секрет нужной задаче/шагу. Используйте короткоживущие токены (например, OIDC), чтобы сократить долгоживущие ключи в покое.

3

Регулярно ротируйте секреты

В случае кражи короткий срок жизни ограничивает ущерб. Сделайте ротацию рутиной, и ротируйте немедленно при сообщении об инциденте в цепочке поставок.

4

Мониторьте исходящий трафик 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

Читать дальше

FAQ

QВ чём была первопричина инцидента с Codecov?
A

Не баг в вашем коде, а изменение доверенного внешнего инструмента, который вы запускаете в CI (Bash Uploader от Codecov), в его источнике (upstream). CI загружал скрипт через curl и запускал его без проверки содержимого, поэтому запускалась изменённая версия, и переменные окружения CI (секреты) уходили наружу.

QПочему это оставалось незамеченным ~2 месяца?
A

Потому что изменённым был чужой инструмент. Ваш собственный репозиторий и код не трогали, и в логах ничего явно подозрительного не появлялось. В итоге это поймали, когда клиент сравнил контрольную сумму скрипта (SHA256) с официальным значением и нашёл несовпадение.

QИмеет ли это значение для небольших проектов?
A

Да. Подтягивание инструментов в CI через «curl … | bash» распространено даже в одиночку, и если скрипт изменён в источнике, один запуск может отправить ваши секреты CI наружу. Меры защиты отсюда (закрепление версии + проверка контрольной суммы загружаемых артефактов, минимальные привилегии секретов CI, регулярная ротация) работают в любом масштабе.