OpenSSF Scorecard / ビルドの守り方

Pinned-Dependencies
依存のバージョンが固定されているか

ビルドや CI が使う依存が、動くたびに変わりうる指定になっていないかを見るチェックです。CI の設定ファイルや Dockerfile が主な対象で、アプリケーションの依存そのものを見ているわけではありません。

何を見るチェックか

Scorecard は、ビルドに関わるファイルの中で、 **「実行するたびに中身が変わりうる指定」**が使われていないかを探します。

主に見ているのは次の場所です。

  • GitHub Actions のワークフロー(uses: actions/checkout@v4 のようなタグ指定)
  • DockerfileFROM node:22(タグ指定)や、curl | bash のような取得実行
  • CI から呼ばれるインストールコマンド(npm installpip install など)

タグやブランチではなく、変わらない識別子(コミットハッシュやダイジェスト)で 指定されているかが評価されます。

たとえば uses: actions/checkout@v4 はタグ指定なので減点対象で、 uses: actions/checkout@a1b2c3...(コミットSHA)は固定されているとみなされます。

点が低いと何を意味するか

点が低いということは、同じソースをビルドしても、時期によって違うものが入る可能性がある、 という意味です。

これが問題になるのは、依存の側が乗っ取られた場合です。

  • あるタグが、後から別のコミットを指すように付け替えられる
  • インストール先のパッケージが、悪意のあるバージョンに差し替えられる
  • curl | bash の取得先が書き換わる

このとき、固定していれば「昨日と同じもの」が入りますが、 固定していなければ差し替えられた側が入ってきます。

CI は多くの場合、リポジトリへの書き込み権限を持つトークンを握っています。 そこに任意のコードが入ることの影響は小さくありません。

誤解しやすい点

「固定していない=危険」と単純化しないでください。

  • アプリ側の依存はロックファイルで固定されているのが普通です。 package-lock.jsonpoetry.lockcomposer.lock などがあれば、 実際のインストール内容は固定されています。 このチェックが見ているのは主に CI とコンテナのビルド手順であって、 アプリの依存全体ではありません。

  • 固定にはコストがあります。 すべてをコミットハッシュで固定すると、更新のたびにハッシュを書き換える必要があり、 自動更新の仕組みを併用しないと古い依存が放置されます。 固定していれば安全、ではなく、固定+更新の仕組みの両方が要ります。

  • 公式が推奨するタグ指定でも減点されます。 actions/checkout@v4 は GitHub 自身が案内している書き方ですが、Scorecard では減点対象です。 「推奨に従っているのに点が低い」という状況は普通に起こります。

つまり、この点が低いプロジェクトは珍しくありません。 低いこと自体より、依存を更新する仕組みがあるかどうかを併せて見てください。

採用する側が確認すべきこと

このチェックは、あなたがそのライブラリを使うときの危険度より、 そのプロジェクトのビルドが乗っ取られる余地を示すものです。

見るべきなのは次の点です。

  1. リリース成果物が、CI で自動生成されているか。 自動生成であれば、CI が汚染されたときにリリースにも影響します。

  2. リリースに署名があるか。Signed-Releases 署名や来歴(provenance)があれば、成果物が想定どおりに作られたことを確認できます。

  3. あなた自身のプロジェクト側でロックファイルを使っているか。 これはあなたが自分でできる対策です。 ロックファイルをコミットし、CI では npm ci / composer installupdate ではなく)を使います。

相手側の固定状況は変えられませんが、自分側の固定は今日からできます。

メンテナーなら何を改善できるか

段階的に進めるのが現実的です。

  1. GitHub Actions をコミットSHAで固定する。

    # 前
    uses: actions/checkout@v4
    # 後(コメントでタグを残しておくと読みやすい)
    uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
    
  2. Dockerfile のベースイメージをダイジェストで固定する。

    FROM node:22-slim@sha256:....
    
  3. curl ... | bash をやめる。 取得したものをハッシュで検証してから実行する形にします。

  4. 固定したら、必ず自動更新を入れる。 Dependabot は github-actions エコシステムに対応しており、 SHA 固定のまま更新 PR を出してくれます。 → Dependency-Update-Tool

4 を入れずに 1〜3 だけをやると、古い依存が固定されたまま残ります。 セットで入れてください。

あわせて読む