Кибербезопасность
Copilot Autofix открыл уязвимость командной инъекции в CI/CD конвейере Snowflake

Безопасный патч, написанный Copilot Autofix от GitHub и объединённый в репозиторий Snowflake 18 июня 2026 года, удалил шаблон очистки ввода и оставил CI/CD конвейер компании открытым для командной инъекции, а через пять дней автономный исследовательский агент ИИ обнаружил уязвимость, использовал её и извлек рабочие учётные данные Jira из GitHub Actions runner, Wiz Research сообщил 17 августа 2026 года.
Уязвимость находилась в файле jira_issue.yml, workflow GitHub Actions в snowflakedb/snowflake-connector-net, публичном репозитории .NET коннектора Snowflake. Workflow запускался каждый раз, когда кто‑то открывал issue в GitHub, и подставлял заголовок issue (текст полностью контролируемый автором) непосредственно в shell‑скрипт. Поскольку триггер был issues: opened, любой аккаунт GitHub в интернете мог его вызвать без аутентификации.
«Red Agent» от Wiz, автономный инструмент исследования безопасности, работающий через программу bug bounty Snowflake на HackerOne, отметил workflow, создал рабочий эксплойт и эксфильтровал токен Jira API из окружения runner’а. Snowflake исправил workflow в тот же день, когда получил отчёт, 23 июня 2026 года, сменил учётные данные на следующий день и сообщил Wiz, что журналы аудита не показывают, чтобы кто‑то ещё взаимодействовал с раскрытыми системами в течение пятидневного окна.
«Autofix» удалил санитайзер
Коммит, внедривший инъецируемый шаблон, попал через PR #1218, “SNOW-2069227: Update jira workflows”, объединён 18 июня 2026 года. История pull request показывает, что человек работал над автоматизацией Jira с августа 2025 года — и, на полпути, был добавлен коммит, соавтором которого был Copilot Autofix powered by AI, бот GitHub Advanced Security, генерирующий предлагаемые исправления для оповещений сканирования кода.
Предложение ИИ изменило способ обработки заголовка issue в workflow. Существующий код передавал заголовок через переменную env: и формировал JSON‑payload с помощью jq --arg, шаблон, который удерживает недоверенный текст от попадания в shell. Предлагаемая замена убрала это в пользу прямой подстановки строки:
“ run: | TITLE=$(echo '${{ github.event.issue.title }}' | sed 's/"/\"/g' | sed "s/'/\'/g") “
Экранирование sed выполняется после того, как шаблонизатор GitHub уже подставил заголовок в скрипт. Одиночная кавычка в заголовке выходит из обёртки echo '...', и всё, что следует после неё, исполняется как shell. Официальная документация GitHub по Copilot Autofix описывает функцию как генерирующую «одно предлагаемое исправление для оповещения, которое вы проверяете и применяете сами» — именно на этапе проверки это исправление прошло.
Workflow также содержал условие‑защиту, которое, казалось, ограничивало, кто может его вызвать:
“ if: (github.event_name == 'issues' && github.event.pull_request.user.login != 'whitesource-for-github-com[bot]') “
При событии issue github.event.pull_request всегда равно null, поэтому сравнение всегда истинно. Каждый пользователь GitHub проходил проверку.
Агент с каждой стороны эксплойта
Первая попытка эксфильтрации Red Agent провалилась. Его payload использовал символ комментария #, чтобы поглотить остальную часть инъецированной строки, но комментарий также захватил закрывающую скобку TITLE=$(...), и runner вернул ошибку синтаксиса bash вместо выполнения. По данным Wiz, агент проанализировал ошибку, переписал payload, закрыв блок shell с помощью ; echo ', и попытался снова.
Рабочий payload, переданный в виде заголовка issue, кодировал в base64 переменные окружения runner’а JIRA_API_TOKEN, JIRA_USER_EMAIL и JIRA_BASE_URL и отправлял их внешнему слушателю через curl. Ответ пришёл от Azure‑хостed GitHub Actions runner в течение нескольких секунд.
Восстановленный токен аутентифицировался как qa@snowflake.net на snowflakecomputing.atlassian.net, предоставляя права чтения ко всем проектам Snowflake в областях инженерии, соответствия безопасности и отслеживания баг‑баунти.
Ремедиация Snowflake, объединённая в PR #1402 23 июня 2026 года, восстановила безопасную переменную env: и шаблон разбора jq --arg. Токен Jira был отозван и заменён 24 июня 2026 года. Wiz заявил, что надёжно удалил все данные, полученные в ходе тестирования proof‑of‑concept.
«Snowflake благодарит Wiz за ответственное сообщение об уязвимости и сотрудничество в рамках нашей программы раскрытия уязвимостей и bug bounty, HackerOne», — заявила компания в заявлении, опубликованном вместе с отчётом Wiz. «Сообщение было получено 23 июня 2026 года, сразу же расследовано и устранено, и наше расследование не обнаружило признаков несанкционированного доступа».
Что показывает пятидневное окно
Раскрытие попадает в середину задокументированного шаблона: изменения, поддерживаемые ИИ, проходят проверку быстрее, чем предполагается их безопасность. Собственные журналы аудита Snowflake делают инцидент понятным: они позволяют компании заявить, а Wiz подтвердить, что за время окна экспозиции не было доступа со стороны третьих лиц. Анализ журналов аудита Snowflake подтвердил, что внешние третьи стороны не обращались к конечной точке в течение пятидневного окна.
Хронология также сжимает последовательность, которую отрасль считала гипотетической. Помощник по программированию удалил защитный шаблон, специально внедрённый для предотвращения командных инъекций, потому что у помощника не было записи о причине его существования. Затем атакующий агент нашёл и за несколько дней превратил результат в оружие, самокорректируя эксплойт на основе живого вывода ошибок. Сторона эксплойта действовала без человека за клавиатурой; со стороны кода ИИ сгенерировал изменение, но человек принял предложение и объединил его — именно на этом этапе проверки произошёл сбой.
Отчёт Wiz рекомендует, чтобы AI‑сгенерированные pull‑request проходили тот же статический анализ, что и код, написанный людьми, чтобы команды сокращали срок жизни учётных данных в соответствии со скоростью автоматического обнаружения, и чтобы защитные механизмы блокировали замену структурированных парсеров прямой подстановкой строк. Check Point перенёс проверку запросов AI‑трафика в корпоративные межсетевые экраны этим летом, а Unite.AI освещает побеги агентов из песочницы и агентные системы, достигающие реальных производственных целей по мере созревания атакующей стороны. Инцидент Snowflake — это та же история, рассказанная изнутри CI‑конвейера: уязвимость была активна пять дней, и единственная причина, по которой это выглядит как кейс‑стади, а не уведомление о нарушении, — какой агент пришёл первым.












