- 研究者は Nixpkgsの脆弱性 を発見し、Nixエコシステム全体に悪意あるコードを注入できた経験を共有している
- GitHub Actions の
pull_request_target トリガーを通じて、外部コントリビューターのPRでも機密権限とシークレットが露出しうる構造的リスクを説明している
- 実際に editorconfig-checker と CODEOWNERS 検証ジョブ において、コマンド挿入やシンボリックリンクの活用によって権限昇格が可能であることを実証した
- 発見直後に Nixpkgs管理チームが迅速に脆弱性を修正 し、脆弱なワークフローを無効化するとともに権限運用を再点検した
- 組織のCI/CDインフラでは、信頼できないデータと機密運用の分離、最小権限の付与、ポリシー強化 が重要であると強調している
Nixエコシステム全体をハックする
紹介と背景
- 昨年のNixConで、研究者と同僚のLexiは Nixpkgsの脆弱性 を発表した
- 発見されたこの脆弱性は、サプライチェーン攻撃 によってNixエコシステム全体へ悪意あるコードを挿入できる可能性を開いた
- 脆弱性の検出から報告、収束までがわずか1日で行われた迅速な対応事例である
- 研究者は今年のNixConには参加できないため、本稿でその過程を詳しく整理している
GitHub Actions: 脆弱な標的
- GitHub Actions は、コードリポジトリでさまざまな自動化作業(CI/CD)を支援するシステムである
- ワークフローファイルへのアクセス権さえあればコード挿入が容易であり、そのため サプライチェーン攻撃 の主要な標的となっている
- ワークフローファイルは YAML で書かれ、実行を意図したフォーマットではないため、予期しないセキュリティ脆弱性が存在する
- 単純な例として、コードをプッシュしたときにコマンドを実行するワークフローがある
危険な pull_request_target トリガー
- GitHub Actions には複数のトリガーがあるが、その中でも pull_request_target は通常の pull_request と大きく異なる
- pull_request_target は、フォークからのPRであっても 既定で read/write 権限とシークレットへのアクセス権を持つ
- このトリガーを誤って使うと、信頼できない外部データ が機密権限と結び付けられてしまう
- GitHub公式ドキュメントでもこのリスクは明確に警告されている
- 研究者は Nixpkgs リポジトリ内で pull_request_target を使っている 14個のワークフローを点検 した
editorconfig-checker の脆弱性
- 最初に見つかった脆弱なワークフローは、editorconfig ルールの検査 を目的とするものだった
- 変更ファイルの一覧を計算した後、xargs を使って editorconfig-checker に渡していた
- xargs コマンドのセキュリティ警告 を無視すると、悪意ある設計のファイル名(例: --help)を挿入できる脆弱性が生じる
- これにより editorconfig-checker を任意に操作したり、追加のコマンド実行の可能性が開かれたりする(詳細な分析には追加検討が必要)
codeowners-validator の脆弱性: ローカルファイルの取り込み
- 2つ目の、より深刻な脆弱性は CODEOWNERS ファイル検証ワークフロー で発見された
- このプロセスでは PR のコードをチェックアウトした後、codeowners-validator でファイルを検査していた
- PR提出者は OWNERS ファイルを シンボリックリンクに置き換える ことで、ランナー内の任意ファイルを参照できた(例: アクションの認証情報)
- その結果、検証時に当該ファイルの内容がログへ出力され、read/write 権限を持つ GitHub トークンが露出 した
- このトークンを取得すると、Nixpkgs リポジトリへ直接 push できるようになる
対応と教訓
- 脆弱性の報告後、Nixpkgs メンテナーの infinisil が即座に対応した
- 脆弱なワークフローを一時的に無効化
- 信頼できないデータと権限の結び付き部分を修正・分離
- セキュリティ修正後にワークフロー名を変更し、branch targeting の問題を緩和
- 主な教訓
- 信頼できないデータ とシークレット、機密作業の結合は絶対に避けるか、最大限の注意を払うこと
- 最小権限運用 の原則を守ること
- GitHub Actions の権限に関する 公式ガイドの理解 が必須
- 類似の脆弱性が発生した場合、組織の管理者はポリシーによって一括で Actions を無効化できる(設定方法の案内あり)
結論
- 研究者はわずか1日で、Nixエコシステム全体を危険にさらしかねない脆弱性 を発見し、報告し、修正にも参加した
- これにより、GitHub Actions、特に pull_request_target の利用時には格別の注意が必要であることが明らかになった
- 研究を支援した KITCTFのIntrigus と、迅速に対応した infinisil に感謝を伝えている
- 関心のある読者には、発表動画や追加資料の参照を勧めている
- 全体として、GitHub Actions のセキュリティ管理の 重要性と実践的な教訓 を強調している
1件のコメント
Hacker Newsの意見
私は
pull_request_targetは本質的に安全でないと思っており、GitHub はこの機能を完全に廃止すべきだと考える。一般にはpull_request_targetを安全に使うには、ブランチ側で制御されるコードをジョブ中に実行しなければよいと言われるが、実際には引数インジェクションやローカルファイルインクルードなどにより、脆弱性の表面ははるかに広い。現在の正当なユースケースは、サードパーティー PR への自動ラベル付けや自動コメント程度だ。そうした作業のために、わざわざデフォルトでリポジトリへの書き込み権限を与える必要はないと思う。GitHub では、その作業のみに限定されたトークンを発行できるべきだ。なので私は zizmor でpull_request_targetのような危険なトリガーの利用をすべてフラグしている。zizmor dangerous triggers 参照pull_requestワークフローがトリガーされない。こういうときはpull_request_targetが事実上唯一の選択肢になる。GitHub がむしろ、マージがクリーンでない PR に対してワークフローを実行できる設定を作り、デフォルトでは無効にしてリンターのような用途にだけ使えるようにしてくれるとよいのだが。それまでは、この制約のせいでpull_request_targetしか使えない現実が本当に残念だ。ちなみにこうした外部ツールを使う場合、GitHub で手動マージすると全体のフローが壊れる。絶対に手動マージ禁止だpull_request_targetを使っている。第一に、ワークフローが常に main 基準で実行されるため、検証されていないテストコードを遮断できる。第二に、ワークフロー内の JWT の sub クレームにjob_workflow_refが決定的に含まれるので、OIDC ベースのシステムで細かなアクセス制御が可能になるpull_request_targetは PR のベースコンテキストで実行されるため、悪意あるコードがリポジトリやシークレットを盗むのを防げることになっている。だが実際には、シークレット流出がどれだけ簡単かを知ると、かなり笑えない話だ私が提案した RFC の通りに Nix チームが署名付きコミット/レビューとは独立した、署名付きの再現可能ビルドを導入していれば、この種のラストマイル供給網攻撃は不可能だったはずだ。結局 NixPkgs は誰でも簡単に編集できることを望んでおり、セキュリティを重視する試みはボランティアを遠ざけるのではないかと恐れている。ホビー向けディストリビューションに注力するのが目的なのだ。それはそれでよいが、こうした性質を人々に明確に伝え、価値あるものを守りたいのであれば、Nix をセキュリティクリティカルな環境で使ったり勧めたりするのはやめるべきだ。何かを守る OS は、すべての変更に対して厳格な二者ハードウェア署名を要求すべきであり、単一のコンピュータや一人の人間に信頼を委ねてはならない。だから Stagex を作った。Stagex リンク Codeberg リンク