
Jira-токен Snowflake: уязвимость, которую в соавторстве подписал Copilot, а человек, по данным GitHub, её написал
- OrcaНОВИНКАOrcaCyber: MiniMax M3.1 Flash Abliterated2026-10-29orca/orcacyber-minimax-m3.1-flash
- OrcaНОВИНКАOrcaCyber: GLM 5.3 Flash Abliterated2026-10-2793 tok/s
- OrcaНОВИНКАOrcaCyber: Qwen3.8 Flash Next Abliterated2026-10-26$0.80 / $1.60 за 1 млн токенов · 260 tok/s
- OrcaНОВИНКАOrcaCyber: MiMo V2.6 Flash Abliterated2026-10-26$0.80 / $1.60 за 1 млн токенов · 92 tok/s
- MoonshotНОВИНКАMoonshotAI: Kimi K3.1 Pro2026-10-2446Интеллект
- OrcaНОВИНКАOrcaCyber: DeepSeek V4.1 Flash Abliterated2026-10-23$0.80 / $1.60 за 1 млн токенов · 104 tok/s
- minimaxНОВИНКАMiniMax: M3.1 Flash2026-10-1929Интеллект
- OrcaНОВИНКАOrca: OrcaCyber Ultra 1.02026-10-17$5.00 / $10.00 за 1 млн токенов · 65 tok/s
- deepseekНОВИНКАDeepSeek: DeepSeek V4.1 Flash 10172026-10-1733Интеллект
- DeepSeekНОВИНКАDeepSeek: DeepSeek V4.1 Flash2026-10-1740Интеллект
- OrcaOrca: OrcaCyber Zero 1.52026-10-10$3.00 / $7.50 за 1 млн токенов · 101 tok/s
- openaiOpenAI: GPT-6.1 Sol2026-09-2955Интеллект
- anthropicAnthropic: Claude Sonnet 5.52026-09-2854Интеллект
- typesafeTypeSafe: Jev 1.132026-09-24$0.04 / $0.00 за 1 млн токенов · 180 tok/s
- OpenAIOpenAI: GPT-6 Luna2026-09-2228Интеллект
- OpenAIOpenAI: GPT-6 Sol2026-09-2248Интеллект
- AnthropicAnthropic: Claude Opus 5.52026-09-2258Интеллект
- xiaomiXiaomi: MiMo-V2.6-Flash2026-09-2127Интеллект
- xiaomiXiaomi: MiMo-V2.6-Pro2026-09-2130Интеллект
- xAIGrok 4.72026-09-2134Интеллект
23 июня 2026 года Red Agent, автономный агент безопасности, созданный Wiz, открыл issue в публичном репозитории GitHub, принадлежащем Snowflake, и получил учетные данные. Репозиторием был snowflakedb/snowflake-connector-net, а workflow .github/workflows/jira_issue.yml, в котором была ошибка, предназначен для создания тикета в Jira всякий раз, когда кто-либо открывает issue, — он встраивал заголовок тикета в shell-команду вместо того чтобы передавать его через переменную окружения, поэтому специально составленный заголовок выполнялся как код на раннере GitHub Actions. Токен, полученный Red Agent, аутентифицировался как qa@snowflake.net на snowflakecomputing.atlassian.net и имел доступ на чтение к Jira-проектам Snowflake в области инженерии, соответствия требованиям безопасности и bug-bounty. Уязвимость оставалась активной пять дней. Wiz опубликовала полный анализ 17 августа 2026 года. Этот инцидент внесен в каталог как запись 2026-08-17-snowflake-jira-zhao-dao-can в Orca AI Incident Archive, который содержит полный набор записей с оценками уверенности и указанными источниками.
Интерполяция и защита, которая так и не сработала
Рабочий процесс срабатывал по событию GitHub «issues: opened». Любой пользователь с аккаунтом GitHub мог запустить его, открыв issue в публичном репозитории — без приглашения, без роли мейнтейнера и без форка. Уязвимый шаг считывал заголовок issue в переменную оболочки: TITLE=$(echo '${{ github.event.issue.title }}' | sed ...), с двумя фильтрами, которые должны были экранировать двойные и одинарные кавычки до сборки строки.
Проблема заключается в порядке операций, а не в экранировании. GitHub подставляет содержимое выражения в текст скрипта ещё до того, как bash начнёт его разбор, поэтому одиночная кавычка внутри заголовка issue закрывает заключённую в кавычки строку, которую удерживает открытой echo. Два фильтра sed выполняются внутри того же скрипта после подстановки и не могут исправить кавычки, которые уже изменили разбор строки. В отчёте Wiz прямо указано, что экранирование происходит слишком поздно, чтобы предотвратить выход за пределы, и что заголовок, составленный с закрывающей кавычкой и точкой с запятой, добавляет команды по выбору атакующего к шагу run.
Второй контроль должен был сузить аудиторию, но не сделал этого. В задании имелось условие if, сравнивающее github.event.pull_request.user.login с логином бота whitesource-for-github-com, очевидно, чтобы автоматические пул-реквесты зависимостей не создавали тикеты. В событии issues объекта пул-реквеста вообще нет, поэтому сравнение идёт со свойством со значением null. Собственная документация GitHub, цитируемая The Hacker News, утверждает, что разыменование несуществующего свойства даёт пустую строку; анализ Wiz приходит к тому же результату через значение null. В любом случае условие оказывалось истинным для каждого пользователя, и исключение для бота превратилось в пропуск для всего интернета.
То, что делало эту инъекцию достойной сообщения, а не рутинной, — это её окружение. На том же шаге JIRA_BASE_URL, JIRA_USER_EMAIL и JIRA_API_TOKEN хранились как переменные среды, поэтому при произвольном выполнении команд на раннере учётные данные оказывались под рукой, а не на пустой основе. Ни один выпуск Snowflake Connector for .NET не был признан затронутым: слабость находилась в автоматизации CI/CD репозитория, а не в поставляемом коде коннектора.
Что взял Red Agent и что, по его словам, он выбросил
Рассказ Wiz об эксплуатации — это то, что отличает данный случай от находки сканера. Первая полезная нагрузка использовала символ решётки, который закомментировал закрывающую скобку присваивания TITLE=$(...), и вызвала синтаксическую ошибку bash вместо колбэка. Агент прочитал ошибку и переписал полезную нагрузку так, чтобы закрыть блок shell точкой с запятой и новой кавычкой echo, после чего получил внеполосный вызов. Полезная нагрузка использовала curl для обращения к поддомену oast.me с base64-кодированными значениями трёх переменных учётных данных, а колбэк пришёл с IP-адреса Azure 20.106.182.197, который Wiz приписывает раннеру GitHub Actions.
Возвращённый им токен был API-токеном Jira для qa@snowflake.net, а Wiz описывает его охват как доступ на чтение к проектам engineering, security-compliance и отслеживания bug-bounty в облачном экземпляре Snowflake в Atlassian. Вот в чём вред, который фиксирует архив: не выполнение кода на сборочной машине на протяжении пяти дней, а учётные данные, позволявшие читать очереди тикетов, куда подаются неисправленные инженерные и security-баги — включая, по описанию Wiz, трекер bug-bounty.

Wiz заявляет, что безопасно удалила всё, к чему получила доступ в ходе проверки концепции. Snowflake в заявлении для CSO Online сообщила, что этот отчёт «был незамедлительно расследован и устранён», и что «наше расследование не выявило доказательств несанкционированного доступа»; в блоге Wiz также отмечается, что Snowflake проверила журналы аудита за пятидневный период и не обнаружила использования третьими сторонами помимо собственных тестовых адресов Wiz. Snowflake не опубликовала эти журналы, поэтому вывод об отсутствии других участников опирается на её объяснения и на резюме Wiz по этому поводу, а не на документы, которые может прочитать кто-либо за пределами обеих организаций.
Кто написал уязвимую строку
Этот вопрос породил вторую, более масштабную историю. PR #1218 под названием «SNOW-2069227: Update jira workflows» 18 июня 2026 года был объединён squash-мержем как коммит 4a1b8ce, и в списке соавторов squash-коммита указан Copilot Autofix powered by AI. Оригинальный заголовок Wiz строился именно на этом: уязвимость описывалась как находящаяся в пул-реквесте, сделанном с помощью GitHub Copilot, и ранние отраслевые публикации пошли по той же линии — заголовок SC Media звучал так: «Агент Wiz находит уязвимость в репозитории Snowflake в коде, соавтором которого является GitHub Copilot Autofix».
Позиция GitHub, о которой сообщает The Next Web и которая кратко изложена в исследовательской заметке Cloud Security Alliance, такова: его внутренняя проверка показала, что «человек написал изменения, которые привели к уязвимости», а Copilot Autofix «не проверял их и не участвовал в их создании». Техническое обоснование этого опровержения находится в истории git. Squash-слияние сводит пул-реквест к одному коммиту и переносит все трейлеры соавторов независимо от того, какие строки затрагивал этот автор, поэтому строка соавтора фиксирует участие в пул-реквесте, а не авторство конкретного фрагмента. Коммит с соавторством Copilot в том же пул-реквесте, 6d0e2fa, изменил jira_close.yml — другой workflow, нежели уязвимый jira_issue.yml. Небезопасная интерполяция приписывается коммиту 094038e от 25 августа 2025 года, который GitHub приписывает инженеру Snowflake sfc-gh-hpathak; PR #1218 поместил этот паттерн в ветку по умолчанию в июне 2026 года.
Wiz не отозвал находку и изменил формулировку в день публикации. В блоге Wiz опубликовано обновление от 19:57 UTC 17 августа, в котором Copilot описывается как «соавтор, который проверил объединённый PR и изменение кода» и «признал его полностью безопасным», не заметив уязвимостей, и признаётся, что «неясно, было ли изменение кода сделано с помощью ИИ». В этом изложении ошибка ИИ относится к проверке, а не к авторству: объединённый пул-реквест нёс соавторскую подпись Copilot, и инъекция сохранилась. CSO Online цитирует технического директора Wiz Ами Луттвака, который говорит, что чёткое определение авторства между людьми и ИИ «становится немного сложнее установить» и что «просто смотреть на соавторов PR недостаточно».

Что объединяет две версии, стоит отделять от того, в чём они расходятся. Обе стороны сходятся в том, что squash-коммит содержит трейлер соавторства Copilot Autofix и что workflow можно было эксплуатировать. Никто не оспаривает, что GitHub Advanced Security сканировал финальную ревизию пул-реквеста, извлёк jira_issue.yml и не выявил инъекцию — Wiz называет это пропуском, а опровержение GitHub касается авторства, а не сканирования. Неразрешённым остаётся вопрос, просматривал ли Copilot уязвимые строки вообще: Wiz утверждает, что проверка выполнялась и пропустила их, GitHub говорит, что инструмент не имел к ним отношения, а логи, которые могли бы разрешить этот вопрос, находятся у одной из двух компаний. В материале приводятся обе версии, а не выбирается одна.
Пять дней — и что изменилось после
Исправление было выполнено быстро после поступления отчёта. Компания Wiz 23 июня отправила отчёт через программу Snowflake на HackerOne под номером #3819931 и в тот же день уведомила службу безопасности Snowflake через Slack; Snowflake приняла PR #1402, коммит 1dc7766, который заменил прямое раскрытие выражений переменными окружения, передаваемыми jq в качестве аргументов. Хронология Wiz относит ротацию токена Jira к 24 июня, и The Hacker News сообщает о том же расхождении. Во введении к отчёту самого Wiz, напротив, говорится, что Snowflake устранила уязвимость и провела ротацию учётных данных «в тот же день» — расхождение внутри первоисточника, которое запись не должна замалчивать. Исправление было внедрено 23 июня; в таблице Wiz ротация датирована 24 июня.
График раскрытия информации определяла Snowflake: Wiz называет крайний срок публичного раскрытия — 25 июля 2026 года, через тридцать дней после решения от 25 июня в соответствии с политикой программы, а анализ был опубликован 17 августа. В заявлении для CSO Online Snowflake сообщила, что компания «ценит ответственный подход Wiz к раскрытию информации» и что она работает с Wiz, чтобы поделиться извлечёнными уроками с отраслью. Ни анализ Wiz, ни материал The Hacker News не содержит идентификатора CVE, оценки CVSS или записи в каталоге известных эксплуатируемых уязвимостей CISA; уязвимость представляла собой конфигурацию рабочего процесса в публичном репозитории, а не поставляемую библиотеку, поэтому она так и не попала в базу данных уязвимостей обычным путём.

Что подтверждают материалы дела, а что — нет
Архив классифицирует это как исследовательскую находку, а не как событие развёртывания, с высокой критичностью, оценкой уверенности A, подтверждённым участием ИИ и зафиксированным реальным ущербом; его дата — 17 августа 2026 года — день публикации Wiz, а сам инцидент охватывает период с 18 по 23 июня. Установленное ядро узкое и проверяемое: публичный рабочий процесс подставлял в shell-команду текст, контролируемый злоумышленником, его защитное условие сравнивалось со свойством, которое в этом событии равно null, токен Jira находился на том же шаге, автономный агент воспользовался этим, а Snowflake в течение суток внесла исправление через слияние и ротировала учётные данные.
Части, которые являются скорее выводом, чем документальным свидетельством, — именно их неформальные пересказы обычно сглаживают. Copilot Autofix документирован как соавтор пул-реквеста и не документирован как автор уязвимых строк; трактовка «ИИ против ИИ», на которой держался первый новостной цикл, была частично отозвана публикующей организацией в течение нескольких часов и опровергнута GitHub. Проверял ли ИИ-обзор объединённого пул-реквеста файл jira_issue.yml — это всё ещё открытый фактический вопрос, а не решённый. А объём доступа, хотя и подробно описан Wiz, не был независимо проверен: ни разрешения Jira, ни запуск workflow, ни запись аудита не были обнародованы.
Схема исправления — та самая, которую собственные рекомендации GitHub предлагали с июля 2025 года: передавать недоверенные данные issue в переменную окружения и передавать их jq в качестве аргумента, а не разворачивать их внутри блока run. Коммит Snowflake, принятый через слияние, делает именно это, и исправленная обработка остаётся в ветке по умолчанию. Для тех, кто рассматривает эту запись как прецедент, устойчивый вывод касается атрибуции, а не инъекции: когда pull request включает нескольких человек и нескольких агентов, трейлер соавтора не позволяет определить, кто написал строку, и в итоге и Wiz, и GitHub сказали об этом разными словами.
