
この記事の要約
- 脆弱性が有効だった期間は5日間で、GitHubのissueタイトルに細工するだけで誰でも任意のコマンドを実行できた。
- 原因は安全だったenv変数+jqの書き方が、直接の文字列展開へ置き換わったこと。
- CopilotはマージされたPRとコード変更を問題なしと判定した。コード変更がAIの支援によるものかは不明。
- Wiz Red Agentは失敗した攻撃のエラーを解析して書き直し、Jiraのトークン取得に成功した。
- Snowflakeは報告当日にパッチを当て、翌日にトークンを入れ替えた。第三者のアクセスは無かった。
Snowflake脆弱性:GitHubの穴からJiraが露出
GitHubの公開リポジトリの穴から社内のJiraを閲覧できる状態になりましたが、露出期間中に第三者のアクセスはありませんでした。 穴が有効だった5日間のうちに、Wizが発見して攻撃の成立まで実証しました。
GitHub Actions(コードの変更に応じて処理を自動実行する仕組み)の設定に、誰でも立てられるissue(課題の報告)のタイトルを通して命令を差し込める穴がありました。穴が有効だった期間とJiraを閲覧できた範囲は、Wiz公式ブログに記載されています。
Wiz Red Agentが5日後に見つけたGitHubの穴
Wiz Red Agentは穴が有効になった5日後の6月23日に、SnowflakeのGitHub組織を走査して発見しました。 対象は公開リポジトリのsnowflakedb/snowflake-connector-netで、問題のファイルはjira_issue.ymlです。issueが開かれると、Jira(課題管理ツール)へ連携する処理を実行する設定でした。
脆弱性が有効になってからWizが結果を公開するまでの流れ(2026年)
- 6月18日PR #1218(コミット4a1b8ce)がマージされ、脆弱性が有効になる
- 6月23日Wiz Red Agentが発見・実証し、HackerOne経由でSnowflakeへ報告(報告番号 #3819931)
- 6月23日Snowflakeが同日中に、ワークフローを修正(コミット1dc7766・PR #1402)
- 6月24日Jiraトークンを入れ替え
- 8月17日Wizが結果を公開
"Crucially, the vulnerability became live on June 18, 2026 - just five days before its discovery - when PR #1218 was merged."(Executive Summary)/"June 23, 2026 - Wiz identified, exploited, and reported vulnerability to Snowflake via HackerOne (report #3819931)"/"June 24, 2026 - Jira token rotated"(いずれも Disclosure Timeline)— Wiz 公式ブログより公式情報を見る →
GitHub Actionsのセキュリティ脆弱性が及んだJiraの範囲
抜き取られたトークンでは、Snowflake社内のJiraにあるエンジニアリング・セキュリティコンプライアンス・バグバウンティ管理の3つのプロジェクトを閲覧できました。 トークン(システムが本人確認に使う文字列)は、ワークフローが環境変数として持っていたJiraの認証情報でした。qa@snowflake.netのアカウントとして社内のAtlassian環境へ認証され、権限は読み取りでした。
Wizは、Snowflakeの監査ログを分析した結果、5日間の露出期間にWiz以外の第三者がアクセスした形跡は無かったとしています。異常なクエリはいずれもWizの試験用IPからのもので、実証中に触れたデータもすべて安全に削除したとのこと。Snowflakeも、不正アクセスの証拠は確認していません。
"The exfiltrated token authenticated as qa@snowflake.net to snowflakecomputing.atlassian.net, granting read access across Snowflake's engineering, security compliance, and bug bounty tracking projects."(Exploitation)/"Comprehensive audit log analysis confirmed that no external third parties accessed the endpoint during the 5-day exposure window. All anomalous queries were strictly matched to Wiz's testing IPs."(Remediation & Forensics)/"our investigation found no evidence of unauthorized access"(Snowflake's Response)/"Wiz confirmed that all data accessed during proof-of-concept testing was securely deleted."(記事冒頭)— Wiz 公式ブログより公式情報を見る →
GitHub Actionsを突いたスクリプトインジェクション
スクリプトインジェクションとは、外から入力できる文字列をプログラムの命令として実行させる攻撃で、今回はissueのタイトルが入口になりました。 インジェクションは英語で「注入」のことで、入力に命令文を紛れ込ませる手口の通称です。起動条件がissueの作成だったため、GitHubのユーザーなら誰でもワークフローを起動できました。
Copilotが通したPRでシェルインジェクションが成り立つ
元のワークフローが備えていた安全な書き方を、PR #1218が直接の文字列展開へ置き換えたことで、シェルインジェクションが成立しました。 シェル(コマンドを解釈して実行するプログラム)に渡る文字列へ命令を混ぜる攻撃が、シェルインジェクションです。変更前と変更後の違いは次のとおりです。
| 内容 | 変更前 | 変更後 |
|---|---|---|
| issueタイトルの受け取り方 | env変数(ISSUE_TITLE)で受け取る | シェルの文字列へ直接展開する |
| 加工の方法 | jq --argでJSONを組み立てる |
sedで引用符を処理する |
| 起動条件 | issues: opened |
同じ |
| 結果 | タイトルは文字列のまま処理される | 未認証のユーザーが実行環境上で任意のコマンドを実行できる |
変更後のワークフローでは、sedによる引用符の処理がGitHubのテンプレート展開(式の部分を実際の値に置き換える処理)より後に動作します。タイトルにシングルクォートを含めるだけで文字列から抜け出せるため、任意のコマンドを実行できました。
PR #1218はコミット4a1b8ceとしてマージされました。Wizが現在掲載している記述では、同じPRでCopilot Autofixの貢献として記録されたのはjira_close.ymlへの別の修正です。問題のjira_issue.ymlの変更が、AIの支援かどうかは不明とされています。
"The workflow triggered on issues: opened - meaning any GitHub user could fire it by opening an issue - and interpolated the attacker-controlled issue title directly into a shell script"/"The sed escaping runs after GitHub's template expansion, a single quote in the title breaks out of echo '...' and allows arbitrary command execution."/"The merged PR removed the repository’s existing safe env: and jq pattern and replaced it with direct ${{ github.event.issue.title }} interpolation, creating the injection vector."/"Copilot Autofix’s documented contribution was a separate fix to jira_close.yml within the same PR."(いずれも The Code Change)— Wiz 公式ブログより公式情報を見る →
コマンドインジェクションを通したGitHub Actionsのif条件
if条件はボットの実行を弾く設定でしたが、issueのイベントでは常に真になるため、実際には誰の実行も拒否していませんでした。 条件が参照するgithub.event.pull_requestは、issueのイベントでは常にnullです。このため条件は「nullはボット名と等しくない」という式になり、GitHubのユーザーは全員この関門を通過できました。
if条件を通過したissueのタイトルが細工されていると、コマンドインジェクション(外部から入力した文字列でコマンドを実行させる攻撃)が成立します。ここまでに出たスクリプトインジェクションやシェルインジェクションも、同じ攻撃の別名です。実際の突かれ方は、Red Agentの動きのとおりです。
"However, on issues events, github.event.pull_request is always null. So the condition reduces to (null != 'whitesource-for-github-com[bot]'). This is always true, and every GitHub user passes the gate."(The Open "Security Gate")— Wiz 公式ブログより公式情報を見る →
Copilotの判定を通った穴をAIエージェントが実証
Copilotは問題なしと判定し、Wiz Red Agentは失敗を解析して攻撃を成立させました。 AIと自動検査の関わりを事実だけ並べると、次のとおりです。
AIと自動検査の関わりと結果
CopilotのAIコードレビューは共著PRを問題なしと判定
CopilotのAIコードレビューは共著者として確認したPRを、重大な脆弱性に気づかないまま問題なしと判定しました。Wizの8月17日付の更新は、CopilotがマージされたPRとコード変更を確認した共著者だったとしています。ただし、コード変更そのものがAIの支援によるものかは、同じ更新で不明と明記されています。
このためAIが脆弱性を出力したと断定はできません。ただしAIによるレビューが重大な脆弱性を見逃したことは確かです。 GitHub Advanced Security(GitHubの脆弱性検査機能)は脆弱なワークフローを含む最終版のPRを走査しましたが、重大なインジェクションを指摘しませんでした。
"August 17, 2026, 1957 UTC update: This blog has been updated to clarify that Copilot was a co-author that checked the merged PR and code change, and identified it as all-clear without noticing the critical vulnerabilities. It's unclear whether the code-change was AI-assisted."(記事冒頭の更新注記)/"GitHub Advanced Security scan analyzed the final PR revision, including the vulnerable workflow, but did not flag the critical injection."(Executive Summary)— Wiz 公式ブログより公式情報を見る →
Wiz Red Agentは失敗を解析しコマンドを書き換える
Red Agentは最初の試行で構文エラーが出ましたが、エラーの内容を解析して送信する文字列を書き直し、成功しました。 最初に使ったコメント記号の#がTITLE=$(...)の閉じ括弧までコメントアウトしてしまい、実行環境(ランナー)が構文エラーを表示したためです。
Red Agentはそこで止まらず、送信する文字列に; echo 'を使ってシェルのブロックを正しく閉じます。数秒後にはbase64符号化された認証情報を含む通信が、GitHub Actionsの実行環境からRed Agentの受信先へ送信されました。
DeepSeekを使った自律攻撃の事例も報告されています。
"Rather than stopping or failing, Red Agent:"/"autonomously analyzed the syntax execution error"/"adjusted its payload to use ; echo ' to properly close the shell block, and"/"successfully received the out-of-band callback"(Exploitation・原文の箇条書きを / で連結)— Wiz 公式ブログより公式情報を見る →
AIエージェント時代のGitHub Actionsセキュリティ対策
対策はAIが生成したPRにも人のコードと同じ検査をかけ、認証情報を短命にしてパッチを速く当てることです。 Wizの教訓を現場の行動に置き換えると次の4つになります。
- AIが生成したPRにも人のコードと同じ静的解析とセキュリティ検査をかける
- 安全な書き方を検査で明示的に強制し、直接の文字列展開への置き換えを防ぐ
- 自動での発見が数時間単位で起こる前提で、パッチの周期を短くする
- 認証情報を短命にして盗まれても悪用される時間を短くする
Copilot任せにしないGitHub Actionsの安全な書き方
Copilot任せにせずissueタイトルのような外部入力はenv変数で受けてから参照する書き方を維持し、その書き方が崩れる変更を検査で防ぎます。 元のワークフローはこの書き方でした。Wizが掲載した変更前のコードは次のとおりです。
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
run: jq -n --arg title "$ISSUE_TITLE" ...
AIが生成したPRのレビューでは、今回の穴を踏まえて次の2点を確認します。どちらも今回の脆弱性が成立した条件に対応しています。
- 外部から入力できる値がシェルのスクリプト本文へ直接展開されていないか
- if条件が参照する値がそのイベントで実際に存在するか
WizはAIコーディングツールが確率的なパターンでコードを予測するため、安全でない書き方を再導入する可能性があると指摘しました。安全な書き方を検査で明示的に強制しないと、その書き方を選んだ安全上の意図は失われる可能性があるとも、Wizは言います。 AIコーディングエージェントの乗っ取りも報告されています。
"AI coding tools predict code based on probabilistic patterns, which can inadvertently reintroduce deprecated or insecure shell patterns. AI-generated PRs must undergo the same static analysis and security scrutiny as human code."(Key Takeaways / AI Code Generation Demands Rigorous Oversight)/"Security intent can be lost when safer code patterns are not explicitly enforced. In this incident, the merged PR removed a safe env: + jq parsing pattern and replaced it with direct string interpolation, while the existing security solution failed to flag the resulting injection that led to the exposure."(Key Takeaways / Preventing CI/CD Security Regressions)— Wiz 公式ブログより公式情報を見る →
認証情報の短命化と即日パッチで被害を抑える
認証情報を短命にしてパッチを即日で当てると、突かれても被害が及ぶ時間を短くできます。 Snowflakeは報告を受けた6月23日のうちにワークフローを修正し、安全なenv変数とjq --argの書き方へ完全に戻しました。翌6月24日にはJiraトークンを入れ替えています。
Wizは自動での発見が数時間単位で起こる前提に運用を合わせるよう促し、素早いパッチの周期と短命な認証情報を勧めています。穴を作らない対策に加えて、突かれてから被害を抑えるまでの時間も縮めておくといいでしょう。
Snowflake脆弱性の事例では、issueタイトルをシェルへ直接展開する書き換えをCopilotも問題なしと判定し、穴は5日間開いたままでした。現場が取る行動はまずAI生成のPRにも同じ検査をかけることです。加えて安全な書き方を検査で強制し、認証情報を短命にしてパッチを即日で当てます。
"The vulnerability was live for only five days before an automated agent discovered and validated it. Security operations must adapt to a landscape where automated discovery occurs in hours, requiring rapid patch cycles and short-lived credentials."(Key Takeaways / Collapsing Discovery Windows)/"Same-Day Patching: Snowflake patched the workflow on June 23, 2026 (1dc7766, PR #1402), fully restoring the safe env: variable and jq --arg parsing pattern."/"Credential Revocation: The JIRA token in question was revoked and rotated."(いずれも Remediation & Forensics)— Wiz 公式ブログより公式情報を見る →
FAQ
- この脆弱性はCopilotが作ったのですか?
- Copilotが脆弱性を作ったかどうかは確定していません。Wizは2026年8月17日の更新で、Copilotは共著者として、マージされたPRとコード変更を確認し、問題なしと判定したとしています。一方でコード変更そのものがAIの支援によるものかは不明だと述べています。確実に言えるのは、AIによるレビューが重大な脆弱性を見逃したことです。
- この脆弱性では、どこまでの情報に到達できたのですか?
- 抜き取られたトークンは、qa@snowflake.netとして社内のAtlassian(アトラシアン)環境へ認証されました。権限は読み取りで、エンジニアリング・セキュリティコンプライアンス・バグバウンティ管理の3つのプロジェクトにアクセスできる状態でした。Snowflakeは監査ログの分析で、露出期間中に第三者のアクセスが無かったことを確認しています。
- 同じ脆弱性を防ぐには何をすればよいですか?
- AIが生成したPRも、人が書いたコードと同じ静的解析とセキュリティ検査に通すことです。加えて安全な書き方を明示的に強制する仕組みを置き、直接の文字列展開への置き換えを防ぎます。脆弱性が見つかるまでの期間が短くなっている前提で、認証情報を短命にしてパッチを速く当てる運用も欠かせません。



