秘密の情報が守られずに開いたままになる危険を、開いた錠前で表したイメージ(AI生成)。記事の対象や当日の出来事を撮影したものではありません。加工なし TechDaylight作成(Google Antigravityで生成) / Google 利用規約(生成コンテンツの利用条件)
Rust Security Response Teamは2026年9月21日、Rustの公式ブログで、Miriがすべての環境変数をtarget/ディレクトリに保存していると告知しました。target/をGitHub Actionsでキャッシュしている場合、CIのジョブに渡したシークレットがキャッシュに残り、プルリクエストのCIから読み出せる可能性があります。
同チームは、Miriが保存する環境変数をCARGO_*(CARGO_*_TOKENを除く)とOUT_DIRに限る短期的な修正を行いました。ただし、告知の時点ではこの修正がnightlyに入っていない可能性があるとしています。また、GitHubのリポジトリを対象にした同チームの調査は不完全だった可能性が高いとして、Miriを使うプロジェクトに自分の構成の確認を求めています。該当する場合は対処したうえでキャッシュを削除し、漏れた可能性のあるシークレットのローテーションを検討するよう勧めています。
保存された環境変数が、キャッシュを通じてプルリクエストに渡る
cargo miriは内部でMiriを複数回呼び出すため、Miriはビルドに関係する環境変数を実行のあいだで引き継ぐ必要があります。修正前のMiriは、すべての環境変数をtarget/に保存することでこれを実現していました。target/をキャッシュすれば、保存された環境変数もキャッシュに残ります。同チームは、この挙動はそれ自体が必ずしも脆弱性ではないものの、GitHub Actionsのキャッシュの仕組みと組み合わさると、シークレットがプルリクエストにさらされうるとしています。
告知によれば、よくある構成では、mainなどのブランチで動くCIがキャッシュへ書き込み、プルリクエストのCIはキャッシュを読むだけにしています。キャッシュの汚染を防ぐための分け方ですが、mainでの実行時にシークレットがtarget/に書き込まれれば、それを読み込んだプルリクエストのCIから参照できてしまいます。Rustのプロジェクトは、CIを速くするためにcargo installで作ったバイナリや、ときにはtarget/の中身をキャッシュする傾向があると、同チームは説明しています。
同チームによれば、プルリクエストのCIは、リポジトリにプルリクエストを出せる人なら誰でも起動できます。GitHubは初回のプルリクエストでメンテナーの承認を求めますが、以後のプルリクエストでは、プッシュのたびにCIが再実行されるといいます。そのうえで同チームは、過去に変更を取り込まれたことのある人なら、キャッシュされたtarget/から情報を取り出すCIを走らせたうえで、2つ目のコミットをプッシュして痕跡を隠せると指摘しています。GitHubは上書きされたコミットをUIで表示しない場合があり、CIのログや上書きされたコミットも数か月後には削除されるため、こうした攻撃は見つけにくいとしています。
該当する条件と、すぐに取れる対処
同チームはGitHubのリポジトリを調べ、この問題があるリポジトリを1件、脆弱ではないとみられるものの注意が必要なリポジトリを7件見つけ、それぞれのメンテナーに連絡したとしています。そのうえで、調査は不完全だった可能性が高いとして、Miriを使っているプロジェクトに、それぞれのGitHub Actionsの構成を確認するよう勧めています。
すぐに取れる対処として、同チームは3つを挙げています。そのジョブのキャッシュを無効にする、シークレットをそのジョブのうちMiriを呼び出さないステップだけに渡す、Miriを一時的に止める、のいずれかです。対処が済んだらキャッシュを削除し、漏れた可能性のあるシークレットのローテーションを検討するよう求めています。
キャッシュの削除とローテーションは、修正版のMiriに切り替えるだけでは代わりになりません。修正は今後の保存を止めるものであり、すでに保存されたキャッシュにシークレットが含まれていれば、それは残るためです。
| 確認する点 | 影響を受ける状態 |
|---|---|
| Miriの実行 | CIでcargo miriを実行している |
| シークレットの渡し方 | cargo miriを実行するステップが、環境変数としてシークレットにアクセスできる(そのステップへの指定、ワークフローのenvでの設定、前のステップが環境に残した場合を含む) |
| キャッシュの対象 | ワークフローがtargetディレクトリをキャッシュしている(actions/cacheやswatinem/rust-cacheで行うことが多い) |
| キャッシュの参照範囲 | プルリクエストからキャッシュを読める(一般的で、意図した使い方であることも多い) |
修正の範囲と、Miriを使わないプロジェクトへの注意
短期的な修正で、Miriが保存するのはCARGO_*の環境変数(CARGO_*_TOKENを除く)とOUT_DIRだけになります。長期的には、Miriに必要な環境変数の一覧を伝えるよりよい方法を、Miriとcargoが見いだす可能性があるとしています。告知は、この修正がまだnightlyで使えない可能性があるとしたうえで、2026年9月22日のnightlyに含まれるMiriでは問題が解消される予定だとしていました。TechDaylightは、当該nightlyへの反映を確認していません。
同チームは、Miriを使っていないプロジェクトにも、公開のキャッシュへ書き込めるジョブがシークレットにアクセスできないようにすることを求めています。多くのツールはシークレットを特別に扱わず、環境全体がファイルシステムに書き出されうることを前提にしているためです。告知は「シークレットで簡単に汚染されうるキャッシュを持つことは悪い習慣だ」(We consider it bad practice to have a cache that can easily be tainted by secrets.)と述べています。
Cargo、Miri、Rustは、環境変数がtarget/にコピーされないことを保証していません。同チームは、今回の件はセキュリティ上の問題として念のため修正したものの、一般にはこの挙動に頼るべきではないとし、Rustの公式ツール以外でも、ビルドスクリプトが環境をコンパイル成果物に保存しうると指摘しています。標準的なcargoのビルドやテストでシークレットやトークンが必要になることはまれだとしており、実務上は、シークレットをジョブ全体の環境変数として渡さず、必要なステップに限って渡すことが対策の中心になります。
この問題は、OpenAIのPredrag Gruevski氏が報告しました。エコシステムの調査には、OpenAIが提供したCodexのアクセスとクレジットを使ったと、同チームは記しています。
次のニュースも、
あなたのもとへ。
RSSで新着記事をまとめてチェック。メールアドレスの登録は不要です。
更新を受け取る →人気記事ランキング
公開後の閲覧数をもとに、
よく読まれた記事を紹介します。

