こんにちは。プロダクト本部プラットフォーム部QAチームの牛木です。
弊社にはライブラリの継続的アップグレードを支援する活動があります。この活動にQAメンバーとして1年間参加しました。活動の内容や、活動を通じて感じたことをお伝えします。
ライブラリの継続的アップグレードを支援する活動とは
この活動は、EOL*1を迎えたライブラリやフレームワークを使わないように、” 継続的 ” にバージョンを ” アップグレードしよう ” という取り組みです。サポート状況の最新情報や、現時点での対応状況などを収集し見える化することにより、対応が遅れているチームに対しリマインドやバージョンアップのサポートなどを行う活動になります。
なぜこのような活動を行っているのでしょうか?
EOLを迎えたライブラリやフレームワークは、セキュリティパッチが提供されなくなるため、脆弱性が発見されても修正されることはありません。もし脆弱性が放置された場合、自社で対応する必要が生じ、対応が遅れるとプロダクト全体がセキュリティインシデントにつながるリスクが高まります。
Webサービスを提供する弊社にとって、セキュリティリスクへの対策は常に重要な課題であり、この活動はその一環として行われています。
QAメンバーとしてなぜ活動に参加することになったのか
QAチームはプロダクト品質の担保を重要な責務と捉えています。プロダクト品質は、機能要件のみならず、セキュリティ品質を含む非機能要件も含まれます。プロダクトの安全性を確保するセキュリティ品質は、プロダクト品質を語る上で不可欠です。QAチームとしても積極的に関与し、貢献したいと考えていました。
また、日々の開発におけるライブラリのアップグレードはプログラム変更の一環であり、本来QAプロセスを経てリリースされるべきです。多くのOSSに支えられている弊社のプロダクトにとって、常に最新の状態を維持するために、継続的なライブラリのアップグレードは避けられません。
QAチームは、このライブラリのアップグレードという一連のプロセスを、開発からリリース、そしてその後の安定稼働まで一貫して見据え、最適化していくことを重要な役割と捉え、上流工程から品質保証に積極的に関与する「シフトレフト」を実践しています。この活動にQAメンバーとして参加することで、要件定義や設計段階からセキュリティ品質の観点を取り入れることが期待できます。それは、セキュリティリスクを低減し、プロダクト全体の品質向上に貢献できる良い機会になると考えました。
1年間何をしたか
週1回の定例MTGを実施し、以下の内容を実施しました。 参加メンバーは、開発エンジニアと私です。
① 使っているライブラリやフレームワークのリリース情報をチェック
新しいバージョンがリリースされた際、リリース内容からSecurity Fixが含まれていないか確認します。新しいバージョンがリリースされたかどうかの確認は、endoflife.dateをよく利用しています。Security Fixが含まれていないかの確認は、CVE*2に関連する改修情報を重点的に確認します。
② Dependabot アラート*3をチェック
新規にCritical・High・Mediumのアラートが発生していないか確認します。 Dependabotアラートは、GitHub のSecurityから閲覧できます。
(Criticalアラートは即潰すをいうルールが定着し、現在ではCriticalアラートがありません!)
③ 自社の開発に影響を与える可能性があるかを判断(トリアージ)
上記①、②で確認されたSecurity FixやDependabotアラートが、自社の開発に影響を与える可能性があるか判断を行います。この判断は私では困難であり、開発エンジニアが判断します。緊急度が高いと判断された場合は、速やかに該当開発チームに連絡します。緊急度がそれほど高くないと判断された場合は、週次で開催される各チームのエンジニアがテックイシューを共有しあう定例のMTGで情報共有するに留めています。
①②どちらも毎週何かしら検知されるため、原則として全てのSecurity FixとDependabotアラートを週次の定例MTGで共有しています。なぜなら「影響しない」「対応不要」という判断はリスクを伴うからです。本当に影響がないのか、対応しなくて良いのかという根拠は、実際にはソースコードの調査が必要ですし、現時点では影響がなくても、将来的なコード修正によって影響が出る可能性もあります。したがって、この活動を通して上がってきたリスクを共有し、アップグレードの推奨は行いますが、最終的な影響確認と対応判断は開発チームに委ねています。つまり、ここでのトリアージは、①②の内容が実際に影響するかどうかを判断するよりも、対応を促進させるための追加情報を提供する場なのです。
④ 月末にEOLのバージョンを使っていないかチェック
リポジトリとバージョンのマトリックス表を使って可視化をしています。EOLを迎えているバージョンを使用しているリポジトリや、間もなくEOLを迎えるバージョンを使用しているリポジトリを塗りつぶして、月末の定例MTGで共有し、関係者へ啓蒙を行います。
①②④のチェックは私が担当しました。 ③の判断や、Security FixやDependabotアラートの読み解きは、開発エンジニアの知見やGeminiのDeep Research*4を活用して実施しています。
この4つの取り組みの中で最も優先度が高いのは「④月末にEOLのバージョンを使っていないかチェック」です。なぜならEOLを迎えたバージョンはSecurity Fixが行われないため、仮に脆弱性が混入していても攻撃されるまで被害に気づけないからです。また、攻撃された場合、すぐさまアップグレードや自社での脆弱性修正は困難です。
その上で、日々のSecurity FixやDependabotアラートへの対応(①、②)を定期的に促すことで、④のようなリスクの高い状況に陥るのを事前に防ぐことができます。これらの日々の対応がスムーズに進む開発チームは、ライブラリアップデートのサイクルが定着し、結果としてEOLを迎えたライブラリの使用を避ける仕組みが自然と構築されます。
この活動の重要な視点
この活動は、全てのライブラリやフレームワークを常に最新バージョンにすることや、Dependabotアラートを全て解消することが目的ではありません。
この活動の重要な視点は、「セキュリティリスク」と「事業リスク」を比較し、相対的な重要性を評価した上で、最適なコストバランスの下でセキュリティリスクを低減させることです。
先に述べた通り、EOLを迎えたライブラリやフレームワークは、セキュリティパッチが提供されなくなるため、もし脆弱性が放置された場合、自社で対応する必要があります。セキュリティリスクが顕在化した場合、開発を全面的に停止して脆弱性対応に追われることになるかもしれません。重要なリリースが控えている時期であれば、顧客に影響が出ますし、最悪の場合サービスの一時停止という判断を迫られる可能性があります。これは、「現時点では発生していないものの、発生すれば事業継続に重大な悪影響を及ぼす事象」です。
このような事態を未然に防ぐため、本活動は管理ではなく、あくまで情報提供と啓蒙活動に重点を置いています。
しかし、可能な限り迅速な対応を推奨しているのも事実です。Security Fixの多くはパッチバージョンとしてリリースされるため、影響範囲が比較的小さいと判断できます。影響範囲の小さい修正をこまめに適用することで、影響範囲を詳細に調査する手間を省くことができます。修正を長期間にわたって累積させると、バージョン間の差分が大きくなり、いざ適用する際に予期せぬ不具合が発生し、プロダクトを壊してしまうリスクが高まります。
QAメンバーとして参加して気づいたQA活動との接点
この活動を通じて、QAチームのテスト施策がセキュリティ品質の防止策としても有効的であることを見出すことができました。
QAチームが整備しているE2E自動テストは、ライブラリやフレームワークのアップグレード対応における迅速な対応を促進する上で重要な役割を果たしています。パッチバージョンの適用に伴う主なリスクは、意図しない変更によるプロダクトの予期せぬ動作です。QAチームでは、基本的な機能フローを網羅した自動テストを準備しており、バージョンアップに伴うリリースの際、この自動テストによるチェックのみで品質を担保できる体制を整えています。
詳しくは以前に書かれた記事をご覧ください。 tech.classi.jp
また、標準観点表やテストテンプレートは、XSSやSQLインジェクションといった脆弱性を検知するのに最適なテストパターンとなっています。 認可に関するテストでは、権限マトリクスを活用したテストテンプレートが定着しており、自動テストにも権限パターンやURL直接入力といった観点が、特定機能だけではなく全機能に対して標準整備され、定期的に自動実行されています。
QAチームが日頃行っている品質保証活動は、機能要件の確認にとどまらず、非機能要件であるセキュリティ品質の確保にも貢献していることを強く実感できました。
QAメンバーとして参加して直面した課題
しかしながら、現状の活動からさらに一歩踏み出し、活動を拡張していくことには、正直なところ難しさを感じています。
第一に、ライブラリやフレームワークに関する深い知識に加え、Webアプリケーションの脆弱性に関する専門的な知識を習得した上で、それが自社プロダクトにどのような影響を与えるかを「判断」するには、現状の活動だけでは不十分でした。この1年は知識や仕組みの理解に留まっていましたが、今後は攻撃の再現手順を理解した上で、実際のコードの状態を確認し、攻撃が成り立つかを確認することが必要だと感じます。実践を行うことで「判断」に繋げることができると考えています。
第二に、この活動が「管理」ではなく「啓蒙と推奨」を重視する以上、その啓蒙を裏付ける専門的な見解や、実施が遅れがちな開発チームへの働きかけは、技術負債の解消という大きな課題と密接に関連しており、QAチームとして直接的な成果を出すことは容易ではありません。例えば、EOLを迎えたライブラリのアップグレード対応は、開発チームが本来進めたい施策を一時中断させ、影響調査やプロダクトのコード修正に多くの工数を割く必要があります。こうした作業は、プロダクト全体の安定性にも関わるため、QAチームだけで推進するのは現実的ではありません。
以下は過去に実施したAngularアップデート対応に関する記事です。こちらにはアップグレード対応時に実際に遭遇した課題が記載されています。 tech.classi.jp
この活動の目指す場所
もし、利用中のライブラリやフレームワークに重大な脆弱性が報告された際、この活動が提供できる価値は2つあると考えています。
① 迅速な現状把握
この活動を通じて全体像を継続的に可視化・共有しているため、どのリポジトリで該当のライブラリやフレームワークが使われているか、また脆弱性のあるバージョンが利用されているかといった情報を即座に特定できます。これにより、緊急時の調査時間を大幅に短縮することが可能です。
② スムーズな対応体制の確立
脆弱性のあるバージョンが判明し、修正適用済みの新バージョンへアップグレードが必要となった場合でも、日々の開発を通してライブラリアップデートのサイクルが定着している開発チームであれば、すぐに作業に取りかかれます。
この活動が最終的に目指すのは、この活動がなくとも上記①、②の対応が開発チームで自律的に行える状態です。 そうなれば、この活動を切り出す必要はなく、適切なアップグレードが当たり前である状態と言えると思います。その状態こそがこの活動のゴールだと認識しています。
おわりに
社内では、これらの将来的なセキュリティリスクへの対策を「セキュリティコストの前払い」と呼んでいます。後々大きな負債として積み上がるだけでなく、実際に問題が発生した際の対応コストは計り知れません。日々の開発の中でどれだけ前払いできるかが重要となります。
この「前払い」をいかに促進できるかが、この活動の次の段階における重要なステップだと考えています。現在利用しているプラットフォームの機能を最大限に活用し、より自動的かつセキュアに開発できるような仕組みづくりが、今後取り組むべき内容だと感じています。
例えば、Content Security Policy*5を活用し脆弱性混入時にすぐ検知できる仕組みや、ライブラリのアップデートを最適化する仕組みなどです。詳しくは以前に書かれた記事をご覧ください。 tech.classi.jp tech.classi.jp
この活動に参加したことで、QAチームの施策がセキュリティ品質に貢献していることに気づけたことは嬉しい収穫でした。一方で、この活動を次の段階へ発展させるにあたり、QAチームの枠組みでどこまで実現できるかはまだ明確ではありません。自身のQA活動にこの経験をどう活かすべきか、模索段階であり、自身の視座の低さを痛感しています。 今後は、QAメンバーとして活動に参加する意義を明確にし、開発チームへの働きかけを強化することで、セキュリティ品質の向上に貢献できるQAチームを目指します。
*1:End of Lifeの略で、セキュリティの更新やバージョンアップの停止をはじめ、サポートの提供が終了することを意味します。
*2:Common Vulnerabilities and Exposuresの略で、公開されているソフトウェアの脆弱性やセキュリティリスクを識別するための共通の識別番号です。 CVE - CVE
*3:GitHubが提供する機能の一つで、プロジェクトが使用している依存関係(ライブラリやパッケージなど)に既知のセキュリティ上の脆弱性が発見された際に、開発者に通知するものです。 Dependabot アラートについて - GitHub Docs
*4:GoogleのAIモデルであるGeminiを活用した、詳細かつ包括的なリサーチレポートを自動的に生成する機能です。Gemini Deep Research — your personal research assistant
*5:ウェブサイトに組み込まれたセキュリティメカニズムであり、主にXSSやデータインジェクション攻撃などの、悪意のあるコンテンツの挿入によって引き起こされる攻撃を軽減するための機能です。コンテンツセキュリティポリシー (CSP) - HTTP | MDN