オープンソース プロジェクトをサプライ チェーン攻撃から守る
2021年11月26日金曜日
典型的なソフトウェア サプライ チェーンと、その接続点で発生する可能性がある攻撃の例
Q1 : デベロッパー アカウントの乗っ取りを防ぐためにするべきことは何ですか?
- 正解 : 多要素認証を利用する(可能ならセキュリティ キー)
- コア メンテナンス担当者向けの共有アカウントを利用する
- パスワードはすべて rot13 で記述する
- IP 許可リストを利用する
理由と解説 : 悪意のある人物がデベロッパー アカウントにアクセスできる場合、既知の貢献者になりすまして悪意のあるコードを送信する可能性があります。貢献者には、commit を送るプラットフォームだけでなく、メールなどの貢献に関連するアカウントに対して、多要素認証(MFA)を使うことを推奨しましょう。可能であれば、MFA の方式でお勧めなのはセキュリティ キーです。
Q2 : 悪意のある commit をマージしないために、するべきことは何ですか?
- 正解 : すべての commit で、commit の作成者以外の誰かによるレビューを必須とする
- すべての commit に対して自動実行テストをする
- すべての commit に対して 'bitcoin' という単語をスキャンする
- 1 年以上前からアカウントを使っている貢献者からの commit のみを受け付ける
理由と解説 : セルフマージ(一方的な変更とも呼ばれます)には、1)貢献者のアカウントを乗っ取った攻撃者がプロジェクトに悪意のあるコードを注入する可能性がある、2)善意の貢献者が意図しないセキュリティ リスクを含む commit をマージする可能性がある、という 2 つのリスクがあります。悪意のあるコードの送信や意図しない脆弱性を回避するために役立つのが、身元が明らかで信頼できる別の人の目です。可能であれば、GitHub のブランチ保護設定などを使い、自動要件として設定しましょう。Allstar などのツールも、この要件の適用に役立ちます。これは、SLSA レベル 4 に対応します。
Q3 : CI/CD パイプラインで使うシークレットはどのように保護しますか?
- 正解 : シークレット マネージャー ツールを利用する
- シークレットへのアクセスを管理するメンテナンス担当者を任命する
- シークレットを環境変数に保存する
- シークレットを別のリポジトリに保存する
理由と解説 : 「多層防御」というセキュリティの考え方は、複数の異なる防御レイヤーを設けてシステムやシークレット * などの機密データを守ることを指します。シークレット マネージャー ツール(GCP ユーザーの Secret Manager や、HashiCorp Vault、CyberArk Conjur、Keywhiz など)を使うと、ソースコードにシークレットをハードコードする必要はなくなり、集中管理や機能の監査を実現できます。また、シークレットの漏洩を防ぐ認可レイヤーを導入することにもなります。
* 機密データを CI システムに保存する場合は、それが CI/CD のためだけに使われることや、パスワードや ID マネージャーに格納するほうが適したデータではないことを確認してください。
Q4 : CI/CD システムを不正利用から守るためにするべきことは何ですか?
- 正解 : 最小権限の原則に従ったアクセス制御を行う
- すべての pull リクエストと commit に対して結合テストを行う
- すべての貢献者に GitHub のロール "Collaborators" を設定する
- ローカルで CI/CD システムを実行する
理由と解説 : デフォルトでプロジェクト リポジトリに対して「必要最低限のアクセス」を付与することで、意図しないアクセスと不正利用の両方から CI/CD システムを守ることができます。テストを行うことは重要ですが、デフォルトですべての commit と pull リクエストに対してレビュー前にテストを実行すると、CI/CD システムのコンピューティング リソースの意図しない不正利用につながる可能性があります。
Q5 : ビルド中のセキュリティ侵害を避けるためにするべきことは何ですか?
- 正解 : ビルドの定義や構成を build.yaml などのコードで定義する
- コードを侵害する時間を攻撃者に与えないように、可能な限りビルド時間を短縮する
- ビルドシステムには LEGO ブランドの部品だけを使い、代替品は認めない
- 攻撃者の手がかりとなるものを残さないように、ビルドログを削除する
理由と解説 : 手動でビルド手順を実行すると、意図しない構成ミスが紛れ込む可能性があります。しかし、ビルド スクリプト(ビルドやビルドの手順を定義した build.yaml などのファイル)を使えば、手動でビルドする必要はなくなります。加えて、悪意のある人物がビルドを改ざんしたり、レビューされていない変更を紛れ込ませたりする機会を減らすことにもなります。これは、SLSA レベル 1~4 に対応します。
Q6 : 依存関係の利用前評価はどのように行うべきですか?
- 正解 : Scorecards や deps.dev などのツールを使ってリスクと推移的な変更を評価する
- パッケージ URL の隣に表示される小さな「鍵」アイコンをチェックする
- GitHub で最低 1,000 個のスターが付いている依存関係のみを利用する
- メンテナンス担当者が一度も変更されていない依存関係のみを利用する
理由と解説 : 1 つの決定的な手法でパッケージが「良い」か「悪い」かを判断することはできません。セキュリティ プロファイルや許容できるリスクは、プロジェクトごとに異なります。プロジェクトにとって依存関係が「安全」であるかどうかを判断するうえで役立つのは、依存関係やどのような変更が推移的に取り込まれるかの情報を集めることです。Open Source Insights(deps.dev)などのツールは、最初のレイヤーと推移的依存関係をマッピングしてくれます。一方の Scorecards は、セキュリティ ポリシー、MFA、ブランチ保護の使用有無など、複数のリスク評価指標に基づいてパッケージのスコアを算出します。
使っている依存関係を把握できたら、定期的に Open Source Vulnerabilities などの脆弱性スキャンツールを実行します。そうすることで、常に最新のリリースやパッチについての情報を得ることができます。多くの脆弱性スキャンツールは、アップグレードの自動適用にも対応しています。
Q7 : ビルドが自分の意図したビルドであることを保証する(すなわち、検証する)ために、何をするべきですか?
- 正解 : 来歴の認証を生成できるビルドサービスを利用する
- 最新の commit をチェックし、信頼できるコミッターのものであることを確認する
- ステガノグラフィーを使ってプロジェクトのロゴをビルドに埋め込む
- リリースのたびに適合テストを行う
理由と解説 : ビルドの出所(ビルドの来歴)とアーティファクトを表示すると、ビルドが改ざんされていないことや、正しいものであることをユーザーに示すことができます。来歴にはさまざまな要素があります。こういった要素を実現する 1 つの方法は、来歴を表示するために必要なデータを生成と認証するビルドサービスを利用することです。これは、SLSA レベル 2~4 に対応します。
Q8 : レジストリからアーティファクトを選ぶ際に、求めるべきことは何ですか?
- 正解 : アーティファクトが暗号学的に検証可能な形で署名されていること
- アーティファクトが(墓から盗み出されて)呪われたものでないこと
- タイムスタンプ : 最新のアーティファクトのみを使う
- 公式認定 : 信頼できるブランドや標準化団体のロゴを探す
理由と解説 : 来歴の生成やビルドの署名は、自分のプロジェクトで行うべきことであるだけでなく(SLSA レベル 2~4)、他者のアーティファクトを使うときも、同じ証明を求めるべきです。ロゴなどのブランドに基づく認定形態は偽造可能で、タイポスクワッティングによって正当性を偽装できます。署名などの偽造できない証明を求めるようにしてください。たとえば Sigstore は、OSS プロジェクトでビルドに署名したり、他者のビルドを検証したりする際に役立ちます。
プロジェクトのセキュリティ改善は継続的な取り組みです。ここで紹介した推奨事項の中には、プロジェクトですぐに採用するのが現実的ではないものもあるかもしれません。しかし、プロジェクトのセキュリティ向上のために行える手順はすべて、正しい方向に向かう一歩です。
オープンソース プロジェクトのセキュリティに関連するリソース :
- SLSA : サプライ チェーンのセキュリティ レベルに関するフレームワーク
- Scorecards : セキュリティのベスト プラクティスの使用状況を測定
- Allstar : セキュリティのベスト プラクティスを強制する GitHub アプリ
- Open Source Insights : オープンソース プロジェクトの依存関係の視覚化と検索
- OSV : オープンソース用の脆弱性データベースと自動化インフラストラクチャ
Reviewed by Eiji Kitamura - Developer Relations Team