ИИ-агент Strix за 25 минут нашёл в Docker-образе Baseten рабочий админ-токен GitHub

Компания strix.ai разрабатывает Strix, автономного ИИ-агента для пентестов (тестирования систем на проникновение). Команде понадобились быстрые и дешёвые вычислительные мощности для запуска чужих ИИ-моделей (инференс), и одним из очевидных вариантов оказался Baseten, платформа с оценкой $13 млрд, на которую полагаются многие серьёзные компании. Но прежде чем доверить стороннему сервису свои и клиентские данные, модели и код, команда strix.ai решила сначала проверить его на прочность и направила Strix на домен *.baseten.co без единого пароля, токена или доступа к исходному коду.
Разведкой, перебором хостов и логов сертификатов, Strix нашёл реестр контейнеров Harbor по адресу gcp-us-east4-zlw.registry.baseten.co. Один из проектов в нём оказался публичным: без какой-либо авторизации агент смог получить список репозиториев, анонимные токены на скачивание и сами образы, манифесты и блобы, включая образ baseten/baseten-app. Внутри него Strix сначала нашёл пару ключей AWS, но проверка вызовом sts:GetCallerIdentity показала, что они мертвы: в ответ пришло InvalidClientTokenId. Тогда агент скачал слои образа, прогнал их через сканер секретов TruffleHog и напрямую изучил конфигурацию образа, и в поле history[].created_by, которое фиксирует, как была создана каждая команда сборки, обнаружился классический персональный токен GitHub: значение переменной GITHUB_TOKEN оказалось прямо подставлено в команду RUN и сохранилось в истории образа.
Strix проверил токен одним безопасным запросом GET /user к API GitHub, ответ 200 подтвердил, что токен рабочий и принадлежит аккаунту basetenbot. Заголовок ответа X-OAuth-Scopes показал область действия repo, а сам аккаунт состоял в организации basetenlabs. Дальнейшая проверка прав, тоже только запросами на чтение, показала: токен давал права администратора и записи (push) на основной репозиторий продукта Baseten, на GitOps-репозиторий, управляющий их кластерами, и на их Homebrew-репозиторий, а также доступ на чтение и запись к другим приватным репозиториям, включая отдельные репозитории конкретных клиентов. Собрав достаточно данных, чтобы исключить ложное срабатывание, команда strix.ai остановилась: не стала клонировать клиентский репозиторий, ничего не запушила и не поменяла ни одной настройки, а сразу написала письмо с раскрытием уязвимости.
Судя по временным меткам истории сборки, шаг с токеном был выполнен 3 марта 2023 года, и токен всё ещё действовал, когда Strix нашёл его в июле 2026-го, то есть больше трёх лет спустя. Причина типична: сборке требовался доступ к приватной зависимости на GitHub, и кто-то передал токен через аргумент сборки Docker, чтобы Git смог авторизоваться. Но Docker может записать значение такого аргумента в метаданные и историю образа, здесь он сохранил именно значение токена, о чём сам Docker прямо предупреждает в своей документации. Есть и вторая ловушка того же рода: команда git config --global записывает URL с токеном внутри в файл настроек Git, так что секрет может остаться в файловой системе образа даже при другом способе передать его в сборку. Правильное решение, механизм BuildKit secret mount (временный способ передать секрет в момент сборки, не оставляющий его в готовом образе), а не аргумент сборки; проверять нужно и слои образа, и его историю, и обязательно отзывать старые токены, правка Dockerfile ничего не меняет для уже скачанных кем-то образов.
Раскрытие прошло быстро. 13 июля в 23:10 команда strix.ai сообщила Baseten о рабочем токене, публичном проекте Harbor и правах репозиториев. Утром 14 июля Baseten закрыла проект Harbor от публичного доступа, но токен на тот момент ещё действовал, об этом сообщили отдельно. В 16:34 того же дня Антон из службы безопасности Baseten подтвердил критичность находки, сообщил, что реестр закрыт, а токен отозван, и попросил безопасно удалить скачанные образы; в 17:05 команда strix.ai подтвердила удаление и передала ещё две находки более низкой критичности из того же скана. 17 июля Baseten закрыла оставшиеся находки. В сентябре strix.ai предупредила Baseten о планах рассказать об инциденте публично и прислала черновик поста. В благодарность за находку Baseten прислала футболки и толстовки, о денежном вознаграждении в посте речи нет.
Авторы подчёркивают: весь путь Strix, от первого касания домена до подтверждённой критической уязвимости, занял около 25 минут, без единой подсказки о том, что вообще стоит искать реестр Harbor или какой-то токен. Для них это довод в пользу того, что атакующие с похожими ИИ-инструментами способны находить такие следы так же быстро, а значит компаниям стоит сканировать себя первыми: проверять, что вообще можно скачать без входа, включая забытые старые теги и проекты; читать историю сборки командой docker history --no-trunc или напрямую смотреть поля history[].created_by в конфигурации образа, а заодно проверять и сами слои; выносить секреты из аргументов сборки в защищённый временный механизм и следить, чтобы команды, использующие эти секреты, не записывали их обратно в образ; ограничивать права токенов сборки минимально необходимыми и задавать им срок действия.
Ключевые факты
- Автономный ИИ-агент Strix (разработка strix.ai) без учётных данных и доступа к коду примерно за 25 минут нашёл в открытом Docker-образе Baseten рабочий персональный токен GitHub.
- Токен попал в историю сборки образа 3 марта 2023 года и всё ещё действовал, когда его нашли в июле 2026-го, больше трёх лет спустя.
- Токен давал права администратора и записи (push) на основной репозиторий продукта Baseten, на GitOps-репозиторий её кластеров и на её Homebrew-репозиторий, а также чтение и запись в другие приватные репозитории, включая отдельные репозитории клиентов.
- Причина утечки, переменная GITHUB_TOKEN, переданная как аргумент сборки Docker и сохранённая в поле history[].created_by конфигурации образа; убрать такой секрет, просто почистив файлы образа, нельзя.
- Baseten (оценка $13 млрд) закрыла публичный доступ к реестру Harbor и отозвала токен уже на следующий день после сообщения; полный цикл устранения, с 13 по 17 июля.
Почему это важно
У истории два слоя. Первый, сама уязвимость: рабочий персональный токен GitHub с правами администратора и записи (push) на основные репозитории Baseten (оценка $13 млрд) пролежал доступным больше трёх лет в истории сборки публично скачиваемого образа, а Baseten как поставщик инференса для сторонних ИИ-продуктов держит в своей инфраструктуре не только свой код, но и репозитории конкретных клиентов. Второй слой, то, как её нашли: автономный ИИ-агент Strix самостоятельно прошёл весь путь от разведки домена до подтверждённого критического токена примерно за 25 минут, без единой подсказки, учётных данных или доступа к коду, и без участия человека на всех этих шагах. Это довод сразу в обе стороны: такие агенты умеют находить критические проблемы в инфраструктуре автономно и быстро, но ровно этой же способностью может воспользоваться и атакующий.
Кому это важно
В первую очередь, командам, которые собирают Docker-образы и передают токены GitHub или другие секреты как аргументы сборки: именно так секрет и попал в историю образа в этом случае. Дальше, любой компании, которая доверяет свои данные и код облачным ИИ-платформам вроде Baseten: у поставщика инфраструктуры тоже может быть незамеченная годами утечка, которая напрямую касается клиентов. И отдельно, командам безопасности и эксплуатации (DevOps), которым эта история даёт готовый список проверок для старых образов и публичных реестров контейнеров, которые давно не пересматривали.
Как это применить
Список конкретных шагов из самой публикации. Проверить, что вообще можно скачать из ваших реестров контейнеров без входа, включая старые теги и проекты, про которые забыли. Прочитать историю сборки командой docker history --no-trunc или напрямую посмотреть поля history[].created_by в конфигурации образа, и заодно проверить слои. Убрать секреты из аргументов сборки и передавать их через механизм вроде BuildKit secret mount (способ временно авторизоваться при сборке, не сохраняя секрет в готовом образе), проследив, чтобы команды, использующие такие секреты, не записывали их обратно в файлы образа. Выяснить, что реально может сделать каждый токен сборки, и выдавать ему только необходимые права с ограниченным сроком действия. И последнее, время от времени запускать что-то вроде Strix против собственной инфраструктуры, а не полагаться на разовый аудит при подключении поставщика.
Можно ли доверять
Источник, блог самой strix.ai, компании-разработчика автономного пентест-агента Strix: у неё прямой маркетинговый интерес показать свой инструмент в деле, и это стоит держать в уме. При этом фактура выглядит добросовестной: авторы приводят точные отметки времени переписки с Baseten вплоть до минут и называют по имени представителя службы безопасности Baseten, Антона, который независимо подтвердил критичность находки, закрытие реестра Harbor и отзыв токена. То есть у истории есть подтверждение со стороны пострадавшей компании, а не только слова нашедших уязвимость. Авторы также прямо пишут, что не пошли дальше проверки, не клонировали клиентский репозиторий и не меняли конфигурацию, это снижает риск, что часть истории приукрашена задним числом. Слабое место, точное число задетых клиентских репозиториев и содержание двух дополнительных находок из того же скана в посте не раскрыты, так что часть картины известна только Baseten.
Риски и подводные камни
Технический риск шире одного инцидента: Docker может записать значение аргумента сборки прямо в метаданные и историю образа, и сам Docker предупреждает об этом в документации, то есть проблема не экзотическая, а системная для любой команды, которая передаёт токены через аргументы сборки. Смежная ловушка, команда git config --global, которая пишет URL с токеном внутри в файл настроек Git, так что секрет может остаться в образе даже при другом способе передать его в сборку. Отдельный риск, сам масштаб прав: токену, нужному только для чтения одной приватной зависимости, дали права администратора и записи на основные репозитории продукта, а разумная практика, минимально необходимые права и обязательный срок действия. И последнее: правка Dockerfile никак не действует на уже скачанные кем-то образы, старую копию токена нужно отзывать отдельно, иначе уязвимость формально «исправлена», а рабочий секрет по-прежнему может лежать в чьём-то локальном кеше.
«Вот почему мы создаём Strix. В последние несколько недель атаки с использованием ИИ стали по-настоящему пугающими, и мы уверены: единственный способ защититься, постоянно атаковать себя самим, чтобы находить такие проблемы (а они будут всегда) раньше, чем это сделают злоумышленники.»
— команда Strix.ai (разработчики агента Strix)