GitHub Actions has a package manager, and it might be the worst

2025/12/08 17:15

GitHub Actions has a package manager, and it might be the worst

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

改良された要約

GitHub Actions には現在ロックファイルが存在しないため、各ワークフロー実行時に可変タグやブランチからすべてのアクションを再解決します。これは

actions/checkout@v4
の変更が後続の実行で使用される SHA を静かに変える可能性があり、再現性を破壊し、攻撃者がビルド間に悪意あるコードを注入できることを意味します。

問題を裏付ける主要な証拠は次の通りです:

  • USENIX Security 2022 の研究では、リポジトリの99.7 %が外部アクションを使用し、97 %が未検証作成者からのものであり、18 %がセキュリティ更新を欠いたアクションを実行していることが判明しました。
  • 静的汚染分析により、270万件以上のワークフローで4,300件以上のコード注入脆弱性が検出されました。
  • コンポジットアクションは内部で依存関係を解決しますが、その依存ツリーを公開しないため、推移的ピンニングは不可能です。

GitHub はイミュータブルリリース、SHA ピンニングポリシー、および作成者検証という限定的な緩和策を提供していますが、これらはトップレベルの依存関係のみを保護します。プラットフォームには中央レジストリやアクション用のセキュリティスキャンもなく、共有可変環境(例:

$PATH
の変更)は非決定的な結果につながる可能性があります。

整合性チェックが欠如していることは、OIDC トークンを使用して GitHub Actions でパッケージを公開する下流エコシステムに脅威をもたらします。攻撃されたアクションはより安全なレジストリへと拡散する可能性があります。すべての解決済み SHA を記録したロックファイルは、完全な依存関係グラフを公開し、推移的ピンニングを可能にし、再現可能なビルドを提供します―これが GitHub またはサードパーティツールによるより強力な保護策の採用を促すきっかけとなり得ます。

本文

ecosyste-ms/package-manager-resolvers
をまとめた後、GitHub Actions が実際にどのような依存解決アルゴリズムを採用しているのか疑問になりました。
workflow ファイルで
uses: actions/checkout@v4
と書くと、依存関係が宣言されます。GitHub はそれを解決し、ダウンロードし、実行します。つまりパッケージ管理です。そこでランナーコードベースに潜り込み、仕組みを調べてみたところ、非常に懸念すべき事実が判明しました。


パッケージマネージャはソフトウェアサプライチェーンセキュリティの中核です

業界は left-pad、event-stream などの事件を受けて数年かけてパッケージマネージャを強化してきました。ロックファイル、整合性ハッシュ、依存関係可視化はオプションではなく基盤です。GitHub Actions はそれらすべてを無視しています。

機能npmCargoNuGetBundlerGoActions
ロックファイル
伝播ピニング
整合性ハッシュ
依存ツリー可視化
解決仕様

核心問題:ロックファイルがない

ほかのパッケージマネージャは何十年も前からこの問題を解決しています。manifest で緩やかな制約を宣言し、リゾルバが特定のバージョンを選択、そしてロックファイルに「これを選んだ」という記録を残します。GitHub Actions は同等の仕組みを持ちません。毎回 workflow ファイルから再解決され、コード自体を変更しなくても結果が変わる可能性があります。

USENIX Security 2022 の研究では 20 万件以上のリポジトリを分析し、以下の事実が明らかになりました。

  • 99.7 % が外部で開発されたアクションを実行
  • 97 % が検証されていない作成者からのアクションを使用
  • 18 % がセキュリティアップデート欠如のアクションを走らせている

研究者は CI/CD システムに必要な四つの基本的安全性プロパティ(受容制御、実行制御、コード制御、シークレットアクセス)を挙げましたが、GitHub Actions はどれも十分に備えていません。静的テイント分析を用いた後続研究では 2.7 百万のワークフロー中 4,300 件以上でコード注入脆弱性が検出され、ほぼすべてのユーザーが第三者コードを検証なしに走らせ、ロックファイルも可視化もない状態で依存関係を持っていることが分かりました。


可変バージョン

actions/checkout@v4
のようにタグを固定しても、そのタグは移動可能です。メンテナは新しいコミットをプッシュし、再タグ付けすることで workflow を静かに変更します。ロックファイルがあれば
@v4
が解決した SHA を記録できるので再現性と可読性の両立が可能です。現在は「読みやすいタグ」か「読みづらい SHA」のどちらかを選ばなければなりません。

GitHub は以下の対策を追加しています。

  • Immutable releases:公開後にリリース git タグをロック
  • 組織ポリシーで SHA ピンニングを強制
  • 検証済み作成者からのアクションのみ許可

これらはトップレベル依存に対して有効ですが、伝播依存(トランジティブ)には何も対処しません。


隠れたトランジティブ依存

SHA ピンニングだけでは解決できません。コンポジットアクションは自身の依存を解決しますが、その内容を見たり制御したりする手段がありません。外側の SHA を固定しても、内部で

some-helper@v1
のような可変タグを引っ張ってくると workflow は脆弱です。ロックファイルは全ての解決ツリーを記録し、トランジティブ依存を可視化・ピンニングできます。

JavaScript アクションの研究では 54 % が少なくとも一つのセキュリティ欠陥を含み、多くは間接的な依存から来ています。

tj-actions/changed-files
の事件では、侵害されたアクションがトランジティブ依存を更新してシークレットを外部へ流出させました。ロックファイルがあれば、予期しないトランジティブ変更は差分で即座に検知できます。


整合性検証の欠如

npm はロックファイルに整合性ハッシュを記録します。Cargo も

Cargo.lock
にチェックサムを書き込みます。インストール時にダウンロード内容が一致するか確認されます。Actions には何もありません。GitHub が SHA の正しいコードを提供してくれることだけを信頼しています。ロックファイルに整合性ハッシュを入れれば、実行中のコードが解決されたものと一致しているか検証できます。


再実行は再現性がない

GitHub のスタッフも明確に言及しています。「workflow があるバージョンのアクションを使用している場合、そのバージョンが強制的にプッシュ/更新されたとき、最新のコードを取得します」。失敗したジョブを再実行すると、元の実行時とは異なるコードが無音で取得されます。キャッシュとの相互作用も問題を悪化させます:キャッシュは成功したジョブにのみ保存されるため、強制プッシュ後の再実行は別のコードでキャッシュを作り直す必要があります。二つの非決定的要因が重なります。ロックファイルがあれば同じロックファイルで同じコードを毎回取得できるので、再実行も deterministic になります。


依存ツリー可視化がない

npm の

npm ls
や Cargo の
cargo tree
のように、完全な依存グラフを確認し、重複やトランジティブ経路を追跡できる機能はありません。Actions では workflow が実際に何に依存しているかを知るために、各コンポジットアクションのソースコードを手動で読む必要があります。ロックファイルがあれば、依存ツリー全体の完全なマニフェストになります。


未文書化の解決セマンティクス

すべてのパッケージマネージャは「どのように依存を解決するか」を明文化しています。npm には仕様、Cargo も仕様があります。Actions の解決方法は未文書化です。ランナーソースコードは公開されており、

ActionManager.cs
に全てが詰まっています。以下はその簡略版です。

// Simplified from actions/runner ActionManager.cs
async Task PrepareActionsAsync(steps) {
    // Start fresh every time – no caching
    DeleteDirectory("_work/_actions");

    await PrepareActionsRecursiveAsync(steps, depth: 0);
}

async Task PrepareActionsRecursiveAsync(actions, depth) {
    if (depth > 10)
        throw new Exception("Composite action depth exceeded max depth 10");

    foreach (var action in actions) {
        // Resolution happens on GitHub's server – opaque to us
        var downloadInfo = await GetDownloadInfoFromGitHub(action.Reference);

        // Download and extract – no integrity verification
        var tarball = await Download(downloadInfo.TarballUrl);
        Extract(tarball, $"_actions/{action.Owner}/{action.Repo}/{downloadInfo.Sha}");

        // If composite, recurse into its dependencies
        var actionYml = Parse($"_actions/{action.Owner}/{action.Repo}/{downloadInfo.Sha}/action.yml");
        if (actionYml.Type == "composite") {
            // These nested actions may use mutable tags – we have no control
            await PrepareActionsRecursiveAsync(actionYml.Steps, depth + 1);
        }
    }
}

ここに見られるのは、バージョン制約もなく、重複した同一アクションが二度ダウンロードされること、整合性チェックがない点です。GitHub の API が tarball URL を返し、その SHA に対して正しい内容を返すと信頼するだけ。ロックファイルは「何が解決されたか」の具体的な記録を提供します。


さらに他にある問題点

レジストリがない

アクションは GitHub リポジトリ内に存在し、中央インデックスやセキュリティスキャン、マルウェア検出、タイプスクワッティング防止機能がありません。実際のレジストリなら悪意あるパッケージをフラグ付けしたり、ソースとは別に不変コピーを保管し、セキュリティ対応の一元化を可能にします。Marketplace はリポジトリ検索上層にすぎず、不変メタデータが存在する場所はありません。アクションのソースリポジトリが消失または侵害された場合、フォールバック手段がないのです。

共有可変環境

アクション同士はサンドボックス化されていません。同じ runner 上で複数のアクションが

setup-node
を呼び出すと
$PATH
が変更され、実行順序に依存した結果になります。決定的な解決とは関係ありません。

オフラインサポートなし

Actions は毎回 GitHub から取得します。オフラインインストールモードやベンダリング機構がなく、ネットワーク不可時は CI が停止します。他のパッケージマネージャは依存をベンダー化したりプライベートミラーを設定できます。

名前空間が GitHub ユーザー名

誰でもアカウントを作ればその名前空間を取得でき、アカウント乗っ取りやタイプスクワッティングが可能です。人気アクションのメンテナアカウントが侵害されると、攻撃者は悪意あるコードをプッシュしタグを再付けできます。ロックファイルに整合性ハッシュを入れれば、コード変更を検知できますが、アカウント乗っ取り自体を防ぐことはできません。Go のチェックサムデータベースのような透明ログで「既知良好」ハッシュを追跡する手段も考えられます。


なぜこうなったのか

Actions ランナーは Azure DevOps をフォークしており、社内タスクライブラリが制御された企業向けに設計されていました。GitHub はその基盤にパブリックマーケットプレイスを追加し、信頼モデルを再考せずに拡張しました。コンポジットアクションや再利用可能ワークフローの導入で依存システムが生まれましたが、実装はロックファイル、整合性検証、トランジティブピンニング、依存可視化といったパッケージ管理から学んだ教訓を無視しています。

この問題は CI/CD を超えて影響します。PyPI、npm、RubyGems などのパッケージレジストリでは GitHub Actions で OIDC トークンを使って直接公開できるようになっています。OIDC は「盗まれた資格情報」という攻撃クラスを排除しますが、逆にサプライチェーンセキュリティは完全に GitHub Actions に委ねられる形になります。ワークフローのアクション依存が侵害されれば、より安全なレジストリに悪意あるパッケージが公開される可能性があります。

GitLab CI は 17.9 バージョンで

integrity
キーワードを追加し、リモートインクルードの SHA‑256 ハッシュを指定できるようにしました。ハッシュ不一致時はパイプライン失敗と明示的に警告します。GitLab は問題を認識して整合性検証を実装したのです。GitHub は同様の機能要求を閉じました。

Forgejo Actions も GitHub Actions と互換性を保っていますが、倫理的理由で Codeberg に移行するプロジェクトは同じ欠陥 CI アーキテクチャを継承します。Forgejo のメンテナは問題点を認めつつ、互換性維持のために取り残されたままです。GitHub の設計不備は代替サービスにも広がっています。


既存の対策とその限界

  • ロックファイルサポート要望(Issue #2195) は 2022 年「未計画」として閉じられました。
  • Palo Alto の “Unpinnable Actions” 研究 は SHA ピンニングだけではトランジティブ依存がピンできないことを示しています。
  • Dependabot がアクションバージョンを更新するのは有用ですが、根本的な機能は提供しません。
  • 自前でベンダリング したり
    zizmor
    のようにワークフローをスキャンして脆弱性を検出する手法もありますが、これらは回避策です。

結論:ロックファイルの必要性

解決済み SHA をすべて記録し(トランジティブも含む)、整合性ハッシュを付与し、依存ツリーを可視化できるロックファイルが不可欠です。GitHub は 3 年前にリクエストを閉じ、再度検討していません。これは単なる「便利」ではなく セキュリティの基盤 に関わる問題です。


参考文献

  • Characterizing the Security of GitHub CI Workflows – Koishybayev et al., USENIX Security 2022
  • ARGUS: A Framework for Staged Static Taint Analysis of GitHub Workflows and Actions – Muralee et al., USENIX Security 2023
  • New GitHub Action supply‑chain attack: reviewdog/action-setup – Wiz Research, 2025
  • Unpinnable Actions: How Malicious Code Can Sneak into Your GitHub Actions Workflows
  • GitHub Actions Worm: Compromising GitHub Repositories Through the Actions Dependency Tree
  • setup‑python: Action can be compromised via mutable dependency

同じ日のほかのニュース

一覧に戻る →

2025/12/09 8:53

Kroger acknowledges that its bet on robotics went too far

## Japanese Translation: > **概要:** > Kroger(クローガー)は、3つのロボット型ECフルフィルメントセンターを閉鎖することを発表し、約26億ドルの費用がかかるものの、EC利益率を約4億ドル向上させる見込みです。今回の閉鎖は、以前に「スピーク」施設を停止した後であり、UKテック企業Ocado(オカド)とのパートナーシップも業績不振により一時停止されたことに続くものです。臨時CEOのロン・サーガント氏は、Krogerが各Ocadoサイトを個別に検討し、大規模な資本投資なしで2,700店舗以上を活用した迅速配送へシフトする方針だと述べました。以前、Krogerは2024年中頃に新しいOcado技術を導入予定でしたが、サイトのパフォーマンスを疑問視し、2023年9月にプロジェクトを停止しました。 > > Pine Street AdvisorsのKen Fenyo氏は、密集都市外にOcadoセンターを配置することが主な欠陥であると指摘しました。低い注文量と長距離がモデルを非収益的にしていたのです。米国消費者はInstacartやDoorDashなどから30分以内の配送を重視し、UKで成功したOcadoの遅めで価格志向のモデルよりも優先します。 > > 今後、Krogerはサードパーティ配達パートナーとの関係強化を図り、高需要市場(AmazonのWhole Foods試験に似た)で資本負担が軽い店舗ベースの自動化をパイロットし、残存するOcadoサイトの運用をケースバイケースで決定します。自動化からの撤退はOcadoにとって大きな後退となり、その株価はIPO前レベルまで下落しています。これは密集都市外でマイクロフルフィルメント技術を導入する難しさを浮き彫りにしています。

2025/12/09 3:51

Jepsen: NATS 2.12.1

## Japanese Translation: (欠落している要素をすべて組み込み、根拠のない推測を除去したもの) --- ## 要約 NATS JetStream のデフォルト「lazy‑fsync」ポリシーは、データをディスクにフラッシュする頻度が 2 分ごとにしか設定されていないため、データ損失およびサービス障害の重大なリスクを生じます。ノードがクラッシュしたり、そのブロック(.blk)やスナップショットファイルが破損すると、最大 78 % のメッセージが消失し、クラスターがクォーラムを失う可能性があります(GitHub issue #7549 および #7556)。協調クラッシュでも、全ストリームが削除されるケース (#6888) や永続的に利用不可になるケース (#7556) が報告されています。この問題は、単一ノードのクラッシュでそのノード上のすべてのデータが消去される点と、2 分間隔という設定が安全なフラッシュ前に約 30 秒分のトラフィックを失うリスク(#7564)を伴うため、さらに深刻です。 JetStream v2.10.22 はクラッシュ時に全ストリームを削除するバグ(v2.10.23 で修正済み)が存在し、スナップショットファイルの切断や単一ビットエラーもノードがストリームデータを削除しクォーラム復旧に失敗して永続的に利用不可になる原因となっていました(#7556)。OS のクラッシュとプロセス停止またはネットワーク分離の組み合わせにより、単一ノードの障害でもデータ損失や持続的なスプリットブレインが発生する可能性があります(#7567)。 NATS は lazy‑fsync ポリシーを文書化していますが、現時点でデフォルト設定変更を推奨していません。Jepsen は fsync を「always」に設定するか、ユーザーに対して相関失敗リスクを強調するよう勧告しています。JetStream のドキュメントが主張する線形性(linearizability)と「自己修復・常時可用性」は非同期ネットワークの CAP 定理に矛盾し、Jepsen もこの点を指摘しています。 Jepsen の LazyFS テストは、書き込みをディスクフラッシュ前にバッファリングするシステムで電源障害をシミュレートし、同様の相関ハードウェア障害が類似した失敗を引き起こすことを示しています。NATS は issue #7549、#7556、および #7567 を積極的に調査中であり、クラッシュ削除バグ(#6888)は v2.10.23 で修正済みですが、lazy fsync のドキュメントは残り変更されていません。

2025/12/09 4:44

Icons in Menus Everywhere – Send Help

## Japanese Translation: 改善されたまとめ この記事は、macOS のデフォルト設定で全てのメニュー項目にアイコンを付ける慣習を批判し、多くの場合可視性の「補填」のために追加されていると主張しています。Google Sheets を極端な例として挙げ、すべてのオプションにアイコンが付いていることを指摘し、同じグループ内でアイコンの有無に不一致がある点や、アイコンがチェックマークやトグル状態と重なるケース(例えば Safari の「Safari」「File」「View」メニュー)も示しています。著者は、macOS が従来はデフォルトでメニューアイコンを避けていたことを指摘し、macOS Tahoe でそれらが広く導入されたことで Apple の 2005 年人間インターフェースガイドライン(任意のシンボルの使用を勧めない)と矛盾していると述べています。 とはいえ、Finder のウィンドウ配置オプション(Top Left, Bottom & Top, Quarters など)は本当に役立つアイコンであり、レイアウト選択を迅速に認識できる点は評価されています。著者は Apple が普遍的なアイコン化へ進むことで、デザイナーが不適切なアイコン使用に対抗しづらくなるとフラストレーションを表明し、メニューの美学に関する継続的な緊張を生んでいると指摘しています。ユーザー側では視覚的な雑然や混乱が起こり得ますが、開発者や UI デザイナーは使いやすさとスタイルのバランスを慎重に取らざるを得ません。この議論は将来の Apple UI ガイドラインに影響し、メニュー設計に関する業界全体の慣行にも波及する可能性があります。