Dependabotに様子見期間を!サプライチェーン攻撃から身を守るパッケージ更新戦略を考える
皆さんはGitHub上で管理するプロジェクトで、依存パッケージの管理をどの様に行っているでしょうか。
今までは、多くの開発現場でDependabotなどのツールを使用し、セキュリティ脆弱性を修正するためにパッケージを常に最新の状態に保つことがベストプラクティスとされてきました。
しかし、npm-debugやchalkといった有名パッケージが侵害される事件が発生しました。ここ数ヶ月で他にも同様の事件が発生していることもあり、常に最新を追い続けることが良いとは言えなくなってきています。
Dependabotが更新PRを挙げてきたらすぐさまmergeするという運用を少し考え直し、一定期間様子見をする「Cooldown」を紹介しようと思います。
最新を追い続けることのメリット
まず今まで私達が行ってきた、最新を追うことは、なぜそうして来たのか再度見直してみます。
- セキュリティ的観点: 重大な脆弱性が発見された際、パッチ済みのバージョンに即座に移行しやすい
- 機能的観点: パフォーマンスや新機能を利用できる
- プロジェクト健全化: 塩漬けしたバージョンを更新するのは非常に難しいですが、こまめな更新はそのコストを大幅に下げる
上記のようなメリットを享受するために行ってきたと考えています。
特にセキュリティ的観点は非常に重要な観点だと考えています。
公開直後に潜むリスク
上記のようなメリットがある一方、常に最新を追うことにはリスクも含まれています。
それが今回の事件で浮き彫りになったサプライチェーン攻撃のリスクです。
悪意のあるコードを仕込んだ新しいバージョンが公開されたとして、Dependabotなどのパッケージ更新ツールの更新検査のタイミングとうまく噛み合ってしまった場合、そのパッケージをインストールしてしまう可能性が出てくるわけです。
解決策: Cooldownオプションを使用し、アップデートを様子見する
そこで今回紹介するのが、パッケージの更新を意図的に遅らせる「Cooldown」の期間を設けるアプローチです。
これは例えば、npmなどのリポジトリにパッケージが公開されてから、即座にアップデートPRを挙げるのではなく、一定期間様子を見るというアプローチです。
この期間を設けることで、例えばセキュリティベンダが問題を報告し、影響が少ない状態になってから開発者はインストールなどを行える可能性が高まります。
Dependabotでの設定方法
Dependabotを有効化している場合、.github/dependabot.yml
ファイルがリポジトリに存在していると思います。
それに対して、数行程度追加するだけで設定は完了します。
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "daily"
cooldown: # この辺り
default-days: 5
上記の例では毎日pipで管理されているパッケージを検査し、パッケージ公開後5日経ったものをアップデートPRとして上げるということが実現できています。
これにより、コミュニティによってある程度安全性が確認されたバージョンのみがアップデートの対象となり、サプライチェーン攻撃のリスクを大幅に低減できます。
この設定により、DependabotのSecurity Updateも遅延してしまうのではないか、と考えたのですが、アナウンスを見る限り
Key benefits
- Reduce noise from frequent dependency updates.
- Stay responsive to critical security patches.
- Granular control with different cooldowns per semver type.
- Flexible scheduling that works with your existing update intervals.
Security Updateは即座に出してくれるようです、最高ですね。
まとめ
多くのパッケージに依存されるパッケージ類が侵害される可能性が高まっている今、パッケージ管理戦略の再度見直しが必要となりました。
「常に最新に保つ」という原則は重要ですが、そこに「ただし、公開直後は除く」という新しい視点を加えるべきであると、事件を通して感じることが出来ました。
Dependabotのようなパッケージ管理ツールをうまく活用し、より安全な開発環境を構築していきましょう。
余談
最近のバージョン管理ソフトではもう一般的ですが、間接依存のバージョンも指定したlockファイルが生成されるものを利用しましょう。
インストール毎に間接依存のバージョンが変わったら、誤ってインストールしてしまうかもしれませんよ?
Discussion