OpenSSF Scorecard / ソースコードの守り方

Binary-Artifacts
リポジトリに実行可能バイナリが入っていないか

ソースコードのリポジトリに、中身を確認できない実行可能ファイルがコミットされていないかを見るチェックです。テスト用の検体や、正当な用途で入っている場合も同じように減点されます。

何を見るチェックか

Scorecard は、リポジトリの中に実行可能なバイナリが含まれていないかを探します。

対象になるのは、たとえば次のものです。

  • .exe / .dll / .so / .dylib
  • .jar / .war / .class
  • .pyc / .pyo
  • ELF や Mach-O 形式のファイル
  • Gradle Wrapper の gradle-wrapper.jar など

見つかった数に応じて減点され、0個なら 10点です。

なぜ問題になるか。 バイナリは中身を目で読めません。 Pull Request のレビューでも差分が読めず、 そこに何が入っているかを誰も確認できないままリポジトリに残ります。 ソースからビルドし直せないため、再現性も失われます。

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

点が低いということは、レビューでは中身を確認できないファイルがリポジトリに含まれている、 という意味です。

これがリスクになる筋道は次のとおりです。

  • そのバイナリがビルドやテストの過程で実行される場合、 何をしているかを利用者が確認できない
  • リポジトリを取り込んで使う側(vendoring、サブモジュール)に、 中身不明のファイルが一緒に入る
  • 誰かがバイナリを差し替えても、差分レビューでは気づきにくい

実際に、ビルドツールの Wrapper に含まれるバイナリが 差し替えられた事例が報告されたことがあります。

ただし、バイナリがあること自体は攻撃ではありません。 「確認できない領域がある」という指摘です。

誤解しやすい点

正当な理由でバイナリが入っているケースが、たくさんあります。

代表的なもの。

  • gradle-wrapper.jar Gradle を使う Java / Android プロジェクトの標準構成です。 これがあるだけで減点されますが、外して回るものではありません。
  • テスト用の検体。 画像デコーダや解凍ライブラリのテストには、 壊れたファイルや実際のバイナリが要ります。 むしろ検査が丁寧なプロジェクトほど、この種のファイルを持っています。
  • フォントやアイコン。 判定によっては拾われることがあります。
  • 参照実装の比較用バイナリ。

つまり、この項目の減点は「ずさん」ではなく「そういう分野だから」であることが多いです。 点数だけを見て比較すると、テストが充実したライブラリのほうが低く見えます。

また、10点でも配布物が安全という意味ではありません。 このチェックが見ているのは Git リポジトリの中身であって、 npm や PyPI で配られるパッケージの中身ではありません。 レジストリに公開されたパッケージにだけバイナリが混ざっている、 というケースはこの項目では拾えません。

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

  1. Scorecard の詳細結果で、どのファイルが該当したかを見る。 ファイル名が出ます。gradle-wrapper.jar やテスト用データなら、 多くの場合そこで判断は終わります。

  2. そのファイルがビルドやテストで実行されるかを見る。 単なるテストデータなら影響は小さく、 ビルド過程で実行されるなら確認する価値があります。

  3. 実際に配布されるパッケージの中身を見る。 これが本命です。npm packcomposer show などで、 実際にインストールされるファイル一覧を確認できます。 リポジトリよりも、配布物のほうがあなたに直接影響します。

  4. Signed-Releases と合わせて見る。 配布物に来歴や署名があれば、何から作られたかを確認できます。

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

消せるものは消す

  • ビルド成果物(dist/build/.pyc)は .gitignore に入れ、 リポジトリから削除します
  • 過去のコミットに残っている分は履歴に残りますが、 現在のツリーから消えていれば Scorecard の対象からは外れます

消せないものは、説明を残す

gradle-wrapper.jar やテスト検体のように、外せないものもあります。 その場合は、

  • なぜ必要かを README か、そのディレクトリの README に書く
  • チェックサムを併記する(Gradle Wrapper なら gradle-wrapper.propertiesdistributionSha256Sum を設定する)
  • テスト検体は専用ディレクトリにまとめる。 tests/fixtures/ のように、用途が名前で分かる場所に集めます

Scorecard に例外を伝える

scorecard.yml(Annotations)で、該当項目に理由を記述できます。 評価が上がるわけではありませんが、 なぜその点なのかを見た人が読めるようになります。 点を隠すのではなく、事情を明示するのが誠実なやり方です。

あわせて読む