暗いスレート色の背景に生成された抽象イラスト:淡いシアンとアンバー色の細い光の線からなる長い水平のリボンが端から端まで走り、中央付近の一点で途切れ、1つの明るいアンバー色の破片が上方の空の暗いチャネルへと逃げるように上昇する。かすかな同心円と罫線格子がパイプラインを思わせる。文字、人物、組織のロゴは表示されない。OrcaRouterのロゴが右下隅に合成されている。
AI Safety Incidents

SnowflakeのJiraトークン:Copilotが共同署名した欠陥、そしてGitHubが「書いた」と主張する人間

著者

Gideon Frost

公開日

最新モデル · 20すべてのモデルを見る →
ベンチマーク:Artificial Analysis · 毎日更新
すべての記事に戻る

2026年6月23日、Wizが構築した自律型セキュリティエージェントであるRed Agentは、Snowflakeが所有する公開GitHubリポジトリでissueを開き、認証情報を持ち帰った。該当リポジトリはsnowflakedb/snowflake-connector-netで、問題のワークフロー.github/workflows/jira_issue.ymlは、誰かがissueを開くたびにJiraチケットを起票するためのものだった。これはチケットのタイトルを環境変数を介して渡すのではなく、シェルコマンドに組み込んでいたため、細工されたタイトルがGitHub Actionsランナー上でコードとして実行された。Red Agentが回収したトークンはqa@snowflake.netとしてsnowflakecomputing.atlassian.netに対して認証し、Snowflakeのエンジニアリング、セキュリティコンプライアンス、バグバウンティのJiraプロジェクトへの読み取りアクセスを有していた。この脆弱性は5日間有効な状態だった。Wizは2026年8月17日に完全な分析を公開した。このインシデントは、記録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 ...)。文字列が組み立てられる前に二重引用符と単一引用符をエスケープすることを意図した 2 つのフィルターがありました。

失敗はエスケープではなく、処理の順序にある。GitHubはbashが解析する前に式の内容をスクリプトテキストへ置換するため、Issueタイトル内の単一引用符が、echoが開いたまま保持している引用文字列を閉じてしまう。2つのsedフィルターは同じスクリプト内で置換後に実行され、行の解析方法をすでに変えてしまった引用を修復できない。Wizの解説記事は、エスケープが遅すぎて脱出を防げないこと、および閉じ引用符とセミコロンで細工されたタイトルが攻撃者が選んだコマンドを実行ステップに追加すること、を明示している。

2つ目の制御は対象者を絞り込むはずだったが、そうならなかった。そのジョブには、github.event.pull_request.user.login を whitesource-for-github-com ボットのログインと比較する if 条件が含まれており、明らかに、自動化された依存関係プルリクエストがチケットを作成するのを止めるためだった。issues イベントでは pull request オブジェクトがそもそも存在しないため、比較は null プロパティに対して行われる。The Hacker News が引用した GitHub 自身のドキュメントによれば、存在しないプロパティの参照解除は空文字列に評価される。Wiz の分析も null 値を通じて同じ結果に達している。いずれにせよ、この条件はすべてのユーザーに対して true と評価され、ボット向けの例外はインターネット全体へのパススルーになった。

このインジェクションが定型的ではなく報告に値するのは、それが置かれていた環境によるものでした。同じステップでは JIRA_BASE_URL、JIRA_USER_EMAIL、JIRA_API_TOKEN が環境変数として保持されていたため、ランナー上での任意コマンド実行には、空白の基盤ではなく、資格情報が手の届くところにありました。影響を受けた Snowflake Connector for .NET のリリースは確認されませんでした。この弱点は、出荷されたコネクタコードではなく、リポジトリの CI/CD 自動化に存在していました。

Red Agentが奪ったもの、そして捨てたと主張しているもの

Wizによるこの悪用の説明こそが、単なるスキャナによる検出とこれを区別する部分である。最初のペイロードはハッシュ文字を使用しており、これがTITLE=$(...)代入の閉じ括弧をコメントアウトし、コールバックではなくbashの構文エラーを引き起こした。エージェントはそのエラーを読み取り、セミコロンと新たなechoクォートでシェルブロックを閉じるようペイロードを書き直し、その後、帯域外コールバックを受信した。ペイロードはcurlを使用して、3つの認証情報変数のbase64エンコードされた値をoast.meのサブドメインへ送信し、コールバックはAzureのIP 20.106.182.197から到達した。WizはこのアドレスをGitHub Actionsのランナーに帰属させている。

返されたトークンはqa@snowflake.netのJira APIトークンであり、Wizはその到達範囲を、SnowflakeのAtlassianクラウドインスタンス上のエンジニアリング、セキュリティコンプライアンス、バグバウンティ追跡プロジェクトにまたがる読み取りアクセスと説明している。これがこのアーカイブに記録された被害である。ビルドマシン上での5日間にわたるコード実行ではなく、未修正のエンジニアリングおよびセキュリティバグが起票されるチケットキュー——Wizの説明によればバグバウンティトラッカーも含む——を読むことができた資格情報なのだ。

A self-built HTML card titled 'What the run step could reach', badged 'snowflakedb/snowflake-connector-net · .github/workflows/jira_issue.yml · 18-23 June 2026'. A left panel lists the environment variables held by the step: JIRA_BASE_URL, JIRA_USER_EMAIL, JIRA_API_TOKEN. A right panel reads: identity qa@snowflake.net; Jira host snowflakecomputing.atlassian.net; access, read across engineering, security-compliance and bug-bounty Jira projects. Three tiles read: trigger 'issues: opened'; account required 'any GitHub user'; token rotated '24 June 2026'. A footer cites Wiz Research, published 17 August 2026, and notes no CVE identifier accompanies the flaw.

Wizは、概念実証中にアクセスしたすべてのものを安全に削除したと述べている。SnowflakeはCSO Onlineへの声明で、その報告は「直ちに調査され、修復された」とし、「当社の調査では不正アクセスの証拠は見つからなかった」と述べた。Wizのブログはさらに、Snowflakeが5日間の監査ログを確認し、Wiz自身のテスト用アドレス以外に第三者の利用は見つからなかったと付け加えている。Snowflakeはこれらのログを公開していないため、他のアクターがいないという調査結果は、両組織の外部の誰もが読める文書ではなく、同社の説明とWizによるその要約に依拠している。

脆弱な行を書いたのは誰ですか

その問いは、2つ目のより大きな記事を生み出した。PR #1218(タイトル「SNOW-2069227: Update jira workflows」)は2026年6月18日にコミット4a1b8ceとしてスカッシュマージされ、そのスカッシュコミットの共著者には「Copilot Autofix powered by AI」が含まれている。Wizの当初の見出しはまさにその点に依拠しており、脆弱性がGitHub Copilot支援のプルリクエスト内にあると表現していた。初期の業界専門メディアの報道も同じ路線を踏襲し、SC Mediaの見出しは「Wiz agent finds Snowflake repo flaw in code co-authored by GitHub Copilot Autofix」だった。

GitHubの立場は、The Next Webが報じ、Cloud Security Allianceの調査ノートで要約されているとおり、同社の社内レビューで「脆弱性につながった貢献は人間が書いた」と判明し、Copilot Autofixは「それらをレビューも貢献もしていない」というものだ。その反論の技術的根拠はgit履歴にある。スクワッシュマージはプルリクエストを単一のコミットに折りたたみ、その作者がどの行に触れたかに関係なくすべての共著者トレーラーを引き継ぐため、共著者行はプルリクエストへの参加を記録するものであり、特定のハンクの authorship ではない。同じプルリクエスト内のCopilotの共著コミット6d0e2faは、脆弱なjira_issue.ymlとは異なるワークフローであるjira_close.ymlを変更した。安全でない補間は、2025年8月25日付のコミット094038eに帰属され、GitHubはそれをSnowflakeのエンジニアsfc-gh-hpathakによるものとしている。PR #1218がそのパターンを2026年6月にデフォルトブランチへ載せた。

Wizはその指摘を撤回せず、公表当日に説明の枠組みを変えた。同社のブログには、8月17日19:57 UTCに投稿された更新情報があり、Copilotを「マージされたPRとコード変更を確認した共同執筆者」と表現して、脆弱性に気づかないまま「問題なしと判定した」とし、「そのコード変更がAI支援によるものかは不明だ」と認めている。その説明では、AIの失敗はレビュー上のものであり、執筆上のものではない。マージされたプルリクエストにはCopilotの共同署名が付いており、インジェクションはそれをすり抜けて残った。CSO OnlineはWizのCTOアミ・ルットワク氏の言葉を引用し、人間とAIの間の明確な帰属を特定することは「少しずつ難しくなっている」と述べ、また「PRの共同執筆者だけを見るのでは不十分だ」と語った。

A self-built HTML card titled 'Two accounts of one commit', badged 'PR #1218 · SNOW-2069227 · squash-merged 18 June 2026 as commit 4a1b8ce'. A cyan-headed left panel, 'GitHub, internal review', reads: a human wrote the contributions that led to the vulnerability; Copilot Autofix neither reviewed nor contributed to them; Copilot's co-authored commit 6d0e2fa changed jira_close.yml, not the vulnerable file; the unsafe pattern traces to commit 094038e of 25 August 2025; squash-merging carries each co-author trailer forward regardless of which lines that author touched. An amber-headed right panel, 'Wiz, blog update, 17 August 2026, 19:57 UTC', reads: Copilot was a co-author that checked the merged PR and code change; it identified it as all-clear without noticing the vulnerabilities; it is unclear whether the code-change was AI-assisted; Copilot Autofix is listed among the squash commit's co-authors; the post was revised on the evening of publication without retracting the finding. Below, an open-question strip asks whether Copilot reviewed jira_issue.yml inside PR #1218, and a dashed band lists what is not in dispute.

2つの説明に共通する部分は、争っている部分から切り分ける価値がある。両者は、スカッシュコミットに Copilot Autofix の共同作成者トレーラーが含まれていること、およびそのワークフローが悪用可能だったことに同意している。どちらも、GitHub Advanced Security がプルリクエストの最終リビジョンをスキャンし、jira_issue.yml を抽出し、インジェクションを検出しなかったことを否定していない。Wiz はこれを見逃しとして報告し、GitHub の反論はスキャンではなく作成者の帰属に関するものだ。未解決なのは、Copilot が脆弱な行をそもそもレビューしたかどうかだ。Wiz はレビューが実行され、それらの行を通過させたと言う。GitHub はツールがそれらの行に関与していないと言い、それを決めるログは2社のうち一方が保持している。記録はどちらかを選ぶのではなく、両方の説明を載せている。

五日、そしてその後何が変わったのか

報告が届いてから、修正は迅速だった。Wizは6月23日、SnowflakeのHackerOneプログラムを通じて報告#3819931として提出し、同日SlackでSnowflakeのセキュリティチームに通知した。SnowflakeはPR #1402、コミット1dc7766をマージし、これにより直接的な式展開を、jqに引数として渡す環境変数に置き換えた。WizのタイムラインではJiraトークンのローテーションを6月24日としており、The Hacker Newsも同じ日付の相違を報じている。一方、Wiz自身の序文では、Snowflakeが脆弱性を修正し、認証情報を「同日に」ローテーションしたと述べている——一次資料内の矛盾であり、記録はこれを覆い隠すべきではない。修正は6月23日に反映され、Wizの表ではローテーションは6月24日付となっている。

開示はSnowflakeの時間軸で進んだ。Wizは公開開示の期限を2026年7月25日としている(プログラムのポリシーに基づく6月25日の解決から30日後)。そして8月17日に分析を公開した。SnowflakeはCSO Onlineへの声明で、同社は「Wizの責任ある報告に感謝する」と述べ、業界と教訓を共有するためWizと協力していると語った。Wizの分析もThe Hacker Newsの報道も、CVE識別子、CVSSスコア、CISAの既知悪用脆弱性カタログへの登録のいずれも持っていない。この欠陥は公開リポジトリ内のワークフロー設定であり、出荷されたライブラリではなかったため、通常の方法で脆弱性データベースに登録されることはなかった。

A self-built HTML card titled 'Five days live, five weeks to publication', subtitled 'Every date below is day-precision, as reported by Wiz Research and The Hacker News'. A vertical timeline lists six entries: 25 August 2025, commit 094038e introduces the unsafe jira_issue.yml refactor, attributed by GitHub to a Snowflake engineer; 18 June 2026, PR #1218 squash-merged as 4a1b8ce and the flaw goes live on the default branch; 23 June 2026, Wiz reports via HackerOne #3819931 and Snowflake merges fix PR #1402 as 1dc7766; 24 June 2026, Jira API token rotated, the fix having landed a day earlier; 25 July 2026, public disclosure deadline under Snowflake's HackerOne policy; 17 August 2026, Wiz publishes the full analysis, blog updated at 19:57 UTC. An amber band reads 'Exposure window: five days, 18 to 23 June 2026'. A footer notes no CVE identifier, CVSS score or known-exploited entry accompanies the record.

記録が何を立証し、何を立証していないか

アーカイブはこれをデプロイ事象ではなく研究成果として分類しており、重大度は高、信頼度はグレードA、AI関与は確認済みで、実際の被害が記録されている。日付は2026年8月17日で、これはWizが公開した日であり、インシデント自体は6月18日から23日に及ぶ。確立された中核部分は限定的で検証可能である。公開ワークフローが攻撃者制御のテキストをシェルコマンドに補間し、そのガード条件が当該イベントではnullとなるプロパティと比較され、同じステップにJiraトークンが存在し、自律エージェントがこれを悪用し、Snowflakeが1日以内に修正をマージして認証情報をローテーションした。

記録ではなく推測に属する部分こそ、軽い語り直しでは平坦化されがちだ。Copilot Autofixはプルリクエストの共同作成者として文書化されており、脆弱な行の作成者としては文書化されていない。最初のニュースサイクルを担ったAI対AIという構図は、報道機関によって数時間以内に一部撤回され、GitHubによって反論された。マージされたプルリクエストのAIレビューがjira_issue.ymlを確認したかどうかは、依然として未解決の事実問題であり、確定した問題ではない。また、アクセスの範囲はWizが詳細に説明しているものの、独立した監査は受けていない。Jiraの権限、ワークフロー実行、監査記録は公開されていない。

修正パターンは、GitHub 自身のガイダンスが2025年7月以降推奨してきたものだ。信頼できない issue データを環境変数に渡し、run ブロック内で展開するのではなく、引数として jq に渡す。Snowflake のマージ済みコミットはまさにそうしており、修正後の処理はデフォルトブランチに残っている。この記録を前例として読む人にとって、長く残る知見はインジェクションではなく帰属に関するものだ。プルリクエストに複数の人間と複数のエージェントが関わっている場合、共著者トレーラーでは誰がどの行を書いたのか分からず、Wiz と GitHub の両方が最終的に異なる言葉でそう述べている。