GitHub Dependabot Alertを愚直に潰し込んだ話

こんにちは、セキュリティチームでソフトウェアエンジニアをしてる@sota1235です。

明けましておめでとうございます!本年も10X Product Blogを何卒よろしくお願いします。

さて、今回はセキュリティチームで今年の6月ごろから取り組んできたGitHub Dependabot Alertの削減についてお話しします。

サマリーとしては以下です。

  • 今年の6月頃から取り組みを開始
  • 初期はセキュリティチームで毎日トリアージ、泥臭くAlertの対応を行う
  • 主要なRepositoryのAlertは一通り解消、一部は担当チームへの移譲等を行い継続的に維持できる状態へ

結果として半年間で500件弱のAlertをcloseし、残ってるAlertも対応方針が全て確定した状態になりました。

この数が多いか少ないかはソースコードの規模感にも依存するので言及しませんが、この記事では小さいリソースで取り組みを始めて、全てのAlertをハンドリングした状態に半年でたどり着いた過程について赤裸々にお話しできればと思います。

課題感

ベースの考え方

10Xのセキュリティチームの意思決定、考え方の基準は以下に基づいています。

  • プロダクト全体を俯瞰した時にCriticalなセキュリティリスクに対応する
  • 中長期でプロダクトセキュリティのレベルを底上げする仕組みに投資する

前者はいわば火消しに近く、発火してないもののプロダクトや会社のリスクになりうるものに対応します。

合わせてそれらのリスクが再発しない仕組みを整えていくのが後者です。

10Xでは常に決まった割合でこれらに取り組んでいるわけではなく、その時々で重要性を判断しながら柔軟に優先度を決めて取り組みを行っています。

当時の取り組みの温度感

10Xのプロダクトでは主にDart、Node.jsを利用しておりpubnpmと言った言語コミュニティが提供するエコシステムを活用しています。

その中で考えなければいけないのが、それらに含まれる脆弱性が公開された際の対応です。

10Xでは直ちに攻撃につながるCriticalな脆弱性等は最低限、キャッチアップし即座に修正をしていましたが軽微な脆弱性や実際の被害に繋がりにくい脆弱性に関しては能動的に対応する体制がありませんでした。

課題感

こうした利用パッケージ等に含まれる脆弱性は典型的な「直せるなら絶対に直したほうがいい」案件です。しかしながら継続的に対応を維持し続けるための体制や運用コスト、そのリターンを考えると踏み込むのが難しく、10Xでは手付かずの領域でした。

一方で当時は事業の成長を見込んで開発チームの体制変更やアーキテクチャの改善等に向けての取り組みが徐々に始まっていました。

この流れが加速すると脆弱性の対応コストも比例して上がっていくことが見込まれたため、まずはセキュリティチームで小さくスタートすることにFocusして取り組みを始めることにしました。

技術選定

脆弱性管理において利用できるツールは有償・無償問わず多くあります。よく聞くところだとSnyk、国産だとyamoryなんかがあるのかなと思います。

トリアージの効率を高める、トリアージ業務自体を開発チームに委譲する、より精度の高いリスク評価を行うという観点においてはこれらの有償ツールのアドバンテージは大きいのですが10XのセキュリティチームはまずGitHubのDependabot Alertを活用することにしました。

docs.github.com

理由としては以下です。

  • まずは小さく始めたいのですでに利用してるサービスで運用できないか探索する
  • お金がかからないにこしたことはないので、まずはGitHubで完結できないか模索したい
  • GitHub自体は使い慣れたツールであり、すぐに運用を開始できるイメージが持てた

取り組みを進める中でDependabot Alertで足りない機能や手の届かないところが出てきた時に初めて、別サービスを検討しようという話をしました。

結果的にはこのDependabot Alertのみを使いこなして半年間でAlert対応を進めることになります。

取り組みの進め方

フェーズ1 主要サービスのAlertを毎日トリアージ

まずは小さく始める、ということで毎日Alert画面を確認。順番にトリアージを行いました。

セキュリティチームでは元々朝会を行なっていたため、朝会の時間が余ったら取り組むコンテンツとして組み入れました。

具体的に行うのは以下です。

Organization全体のAlertページを確認する

https://github.com/orgs/{organization_name}/security/riskにアクセスすることでOrganization全体のDependabot Alertを含めたセキュリティの検出項目を確認することができます。

このページでDependabotの項目にある affectedをクリックすることでAlertが1件以上あるRepositoryに絞り込むことができます。

このうえでサービスのコアとなるRepositoryに絞ってAlertをチェックしていきます。

Alert一覧を1つ1つ眺める

上記のページから各Repositoryのページに移動し、1つ1つAlertを眺めます。

モザイクの向こう側を見たい人は入社してね

このAlert画面では重要度や時系列等でSortすることができます。defaultではさまざまな情報を加味されたGitHubのレコメンドする順になっているのでそれを利用するのが良いかなと思います。

Alertを開くと下記のように脆弱性が含まれるパッケージ、脆弱性の詳細、CVSSを元にしたスコア等が見ることができます。

※この画面は会社のGitHubではなく@sota1235個人repositoryのものです

ものによってはこのページでは情報が不十分な場合もあったのでその際はSnykのデータベースを参照したり、PoCコードを調べることで補完しました。

Alertを評価する

Alertに対して行えるアクションはDismissするか、DependabotのPull Requestを自動生成するかの2つです。

セキュリティチームではDismissするか、Issueを切って対応するかの2択で整理しました。

Dismissする際の基準については以下です。

Dismiss reason どういう時に利用するか
A fix has already been started そのパッケージを更新するような既存プロジェクトがある場合。ほとんど使わない
No bandwidth to fix this 評価の結果、直すべきだが急ぎでないもの。後述する月次の修正で対応する
Risk is tolerable to this project 脆弱性が影響する余地はあるが実害がないもの。
This alert is inaccurate or incorrect Alertの内容がおかしい場合に利用する。1度も使ったことなし
Vulnerable code is not actually used 影響コードが利用されてない場合。例えばserver processで使うと影響があるがCLIとして利用する際には関係ない、みたいなケースがこれに当たる

これらの基準に当てはまらず、なるべく早く直すべきものはIssueを切り、セキュリティチームで対応を行いました。

なお、このAlertは対象の問題がコードの変更によって解消されると自動でCloseされるためDismiss作業は不要です。

月次でまとめて修正を行う

No bandwidth to fix thisでDismissしたものを月初にまとめて修正します。これらはAlert一覧で絞り込みを行うことで参照することができます。

これらの修正が完了したら対象のAlertをReopen -> A fix has already been startedでDismissしておきます。

Dependabot AlertはDismissしたものに対してできるアクションがReopenしかなく、No bandwidth to fix thisとしてmarkしたものを修正済みとしてmarkしなおすにはこの微妙な方法を取ることしかできません…この辺りは今後のアップデートに期待したいと思っています。

この運用をかれこれ4ヶ月。。。

この運用をコツコツ行うことで一番大きなRepositoryのAlert数を大幅に減らすことができました。

この後もこの運用を続け、主要なリポジトリについては全部のAlertをclose。アップデートがされていないものについては修正方針や対応チームが決まった状態に持ち込むことができました。

フェーズ2 全RepositoryのAlertを毎日トリアージ

主要リポジトリのAlertは一掃しましたが、他のリポジトリには依然としてAlertが多くある状態でした。

また、いくつかのRepositoryはDependabot Alert自体が有効化されていない状態でした。

Dependabot Alertを有効化することによるデメリットは基本的にないためOrganization全体でDependabot Alertをdefaultで有効化し、次は全RepositoryのAlertの中で対応すべきものがあるかを考えることにしました。

Organization Ownerであればこのような設定画面が見えるはずです

主要リポジトリ以外なので直ちに影響が出るような脆弱性は少ないものの、歴史の長いリポジトリではAlertが多く放置されてる状態でありセキュリティ対応の割れ窓とならないように対応する必要がありました。

一方で例えばプロダクトと直接関係しない業務改善系のツールが入ってるようなRepositoryはプロダクトのメインRepositoryと同じ温度感で対応する必要はありません。その温度感等をそれぞれのRepositoryの用途を調べながら1つ1つ判断し、対応を行いました。

主な対応アクション

具体的にどのような性質のRepositoryにどのような対応を行なったかざっくりまとめます。

  • ほぼ個人がメンテナンス・利用しているRepository
    • メンテナンスしているメンバーに直接対応を依頼
  • 特定のチームがメンテナンスしているRepository
    • そのチームに継続的なAlertの対応を依頼
    • セキュリティチームでは日次でAlert状況はチェックせず、月次程度で放置されていないかだけをチェック
  • メンテナンス・利用されていなさそうなRepository
    • Archiveできないかを検討
    • Arcihiveしない場合はOwnerを明確にし、対応を依頼

読んでて感じた方もいると思いますが、特別なことはしておらず1つ1つ愚直にコミュニケーションをしながら対応を決めていきました。

特に3点目の使われてないRepositoryに関しては意外と数が多く、棚卸しの良いきっかけになりました。

結果

これらの対応を進めた結果、当初は多く放置されていたAlertを半年足らずで減らす & 残ったAlertの対応方針も確定された状態にできました。

自動でDismissされたものも含みますが、Closeされた件数の推移で見ると成果がもう少しわかりやすいです。

500件弱のAlertをClose!

振り返り

半年間、愚直に取り組むことで小さく始めて、最終的に大きな成果を得ることができました。この過程でいくつか学びがありました。

Alertは意外と増えない

当初、「Alertに対応するスピードとAlertが増加するスピードが拮抗するタイミングが来るのでは」という仮説がありましたが意外と増えませんでした。

これはアーキテクチャにもよると思います。Microservicesのような管理するパッケージ数が増えうるアーキテクチャだとAlertの数が増えるはずです

GitHub Dependabot Alertが意外と使える

こちらも当初の仮説として「使い込んでいくうちに機能の足りなさが目について別サービスを検討することになるかも」というのがありましたが、少なくともこの半年間においては問題なく運用できました。

細々と、痒いところに手が届かない部分があるのも正直なところですがセキュリティチームが小さく脆弱性管理を始めるには必要十分だなと感じています。

いくつか微妙な点を挙げるとすると以下かなと思います。

  • Alert一覧での絞り込みとmonorepo構成の相性が悪い
    • 10Xのメインリポジトリはmonorepoになっていますが、このpackage.jsonに紐づくAlertだけ表示するが今のDependabot Alertだと実現できません
    • これは「monorepoの中のこのモジュールはこの開発チームに委譲したい」といったユースケースを実現する際の壁になるはずです
  • Alert画面が少し貧弱
    • この記事でも触れましたがAlert画面でできるのはDismiss or Reopneするか、DependabotによるPull Requestの自動生成のみです
    • コメントや対応の記録を残すことはできないため、Issue管理ツールと合わせないと対応の記録を残せません

ただ、GitHubのSecurity関連の機能は日々アップデートされておりこの辺りの課題もいずれ解決されるのではと期待しています。

まずはやる、が大事

このような業務はやった方がいいことも、どうやればいいかもソフトウェアエンジニアであればなんとなく頭の中で考えることだと思います。

一方でやってみないと分からない部分も多いので、まずはやる。Just do it!の精神が大事かなと思います。ロジカルではないですが本当にそう思います。

ただ私たちのように人員が限られた体制で取り組むには工夫が必要で、その前提のもと小さく始めてみるのはとても良い選択だったなと思っています。

今後の話

当分はこの運用を継続することでAlertの割れ窓状態を防げると感じています。一方でいくつかは最適化の余地があり、現時点で考えてることに何点か触れます。

パッケージが最新状態に保たれる仕組みを作る

Alertが出たら対応する、を回すことは良いんですがそもそもパッケージのバージョンを最新にし続けることができればAlertが発生する頻度は減らすことができます。

実際にこの半年で対応したAlertの大半は更新が滞った古いパッケージの脆弱性がほとんどです。

社内の一部では始まってる取り組みですが、Renovate等を活用したパッケージ更新の定常化をすることでAlertの数を減らし、対応コストが減らせると考えてます。

Alertチェックの自動化

Dependabot AlertはAPI経由でデータを取ることができるため、運用ルールを反映したツールを実装することで人間がGUIを都度見にいく作業を減らすことができます。

例えばリスクの高いRepositoryはdailyで通知、リスクの低いRepositoryはmonthlyでまとめて通知、Alert対応を委譲してるRepositoryはweeklyで一定の閾値を超えたら通知、みたいな感じのツールを実装すればセキュリティチームがProactiveに動く必要はないんじゃないかと考えてます。

この辺をやりたいならそれこそ類似サービスを検討すべきかもしれませんが、その辺りは実装コストとのバランスかなと思ってます。

スケールを見据えた型化

今の開発組織の規模感であれば「このRepositoryのAlert対応してください」というコミュニケーションが問題なく通じる距離感で開発チームと仕事ができます。

一方で組織が拡大してくるとセキュリティに対する温度感にもムラが出てくることが想定されるため、組織が拡大する前に開発者がAlert対応を効率よく行うためのツールやドキュメンテーションの整備が必要です。

まとめ

今後もやりたいことが尽きない領域ですが、10Xではひとまずこの半年はGitHub Dependabot Alertを使いこなすことでうまいこと脆弱性管理が回せています。

似たような課題感や規模感で悩んでる開発者がいたら参考になれば幸いです。