アプリケーションが孤立して存在しないことはご存知の通りです。それらはオープンソースパッケージ、コンテナ、クラウド管理リソース、VM、APIなどから構成されています。各部分には独自のセキュリティ攻撃対象領域と、独自のスキャナーがあります。静的コード分析ツール(SAST)はソースコードの脆弱性をスキャンし、ソフトウェア構成分析(SCA)ツールは依存関係をスキャンし、クラウドセキュリティツールは設定を監視し、コンテナスキャナーはイメージ内の既知のエクスプロイトを探します。
では、これらすべてのスキャナーを導入すれば、安全なのでしょうか?
ある程度は。確かに各レイヤーをスキャンしています。
しかし、その代償は何でしょうか?
なぜセキュリティスキャナーは誤検知であなたを圧倒するのか
スキャナーは、コード内の脆弱な関数について警告するかもしれませんが、それがアップストリームのAPIによって保護されていることを知りません。あるいは、コンテナのベースレイヤーにあるCVEについて危険を感知するかもしれませんが、実際のアプリケーションがそのコードパスに到達しないという事実には気づきません。同様に、クラウドスキャナーは、権限が過剰なIAMロールを指摘するかもしれませんが、それが本番データにアクセスできないステージングワークロードにのみリンクされていることを認識していません。
その結果、チームは大量の孤立した検出結果に埋もれてしまいます。確かに、それらはすべて技術的には正確ですが、その問題が本当に危険であるかどうかを判断するためのコンテキストがほとんどありません。
あるいは、ある大企業のセキュリティエンジニアが最近言ったように、「脆弱性が当社の最重要資産に影響を与えるのか、それとも仮想ランチメニューに影響を与えるのか、判断できますか?」
誤検知と見逃し(フォールスネガティブ)が単独でリスクである一方で、より大きなリスクは、一見無害な問題が実際のエクスプロイトパスに結合するかどうか、あるいは一見有害な問題の多くが全く問題ではないかを決定する依存関係チェーンを見落とすことです。

そして、私たちは常にチームから次のような声を聞きます。
「依存関係を制御していません。」
その理由は?サプライチェーンの管理が非常に困難だからです。オープンソースパッケージは間接的な依存関係をもたらします。コンテナスキャンやクラウドネイティブツールを使用しても、ほとんどの組織は、何が重要かを自信を持って判断できません。その結果、彼らは受動的に脆弱性を追いかけることになります。
アプリケーションセキュリティとクラウドセキュリティにおいて脆弱性のコンテキストが重要である理由
一般的なSASTまたはSCAツールは、非常に単純で文字通りの見方をします。
例えば、パッケージがCVEにリストされていると認識すると、それをクリティカルとしてフラグ付けします。
それは紙の上ではベストプラクティスのように聞こえます。結局のところ、リスク回避的である方が良いと考えるでしょう。しかし実際には、それは単に誤報を引き起こすだけです。なぜなら:
- 多くの場合、アプリケーションは脆弱な関数を呼び出していません。
- その関数は、あなたが直接触れたことのない推移的依存関係の奥深くに埋もれている可能性があります。
- あるいは、開発者専用で本番環境にはデプロイされないインポートの背後にある場合もあります。
そのため、チームは「クリティカル」な問題の過度に詳細なリストを受け取り、それらを追跡するために何時間も費やしますが、結局それらがクリティカルではないことに気づくことになります。
同時に、エクスプロイトされる可能性のある実際のパスは見過ごされることがあります。
コード、コンテナ、クラウド全体にわたる完全な依存関係グラフの構築
多くのスキャナーがノイズの多い、あるいは不完全な結果を出すのは、明確さを提供するために必要な追加のコンテキストを持っていないためです。従来のツールは、ソースコード、オープンソースパッケージ、コンテナ、クラウドのリソースといった各レイヤーを個別の問題として扱い、多くの場合、別々の製品で処理しています。
これは、それらすべてを統合する単一の依存関係グラフが欠如していることを意味します。依存関係を横断した可視性がないため、重要でない問題の通知を受け取り、実際に重要な問題を見逃す可能性があります。
しかし、可視性はコンテキストだけでなく、一貫性も重要です。パッケージマネージャーはすべて、推移的な脆弱性を異なる方法で管理しています。
例えば:
- JavaScriptのnpm/yarnは依存関係ツリーを提供し、ネストされたパッケージをオーバーライド/ピン留めできます。
- JavaのMavenは予期せぬライブラリバージョンを取り込むことがあり、危険な推移的パッケージを除外するために追加の設定が必要です。
統合されたグラフがないと、チームは出荷したものを把握するためだけに、さらに多くのツールを追加することになります。
一部のエンジニアは「直接インストールしなければ、害はない」と考えがちですが、これが問題をさらに複雑にしています。脆弱性は複数のレイヤーの深さに存在します。
では、チームは何をすべきでしょうか?
依存関係における誤検知を排除するために到達可能性分析を使用します。

真の到達可能性分析とは、「グラフに脆弱なパッケージがあります」と単にフラグを立てるのではなく、プラットフォームがコードが以下の状態であるかどうかを判断できることを意味します。
- 実際に脆弱な関数を呼び出しているか、または
- ユーザー入力に公開された欠陥に関与しているか、または
- インターネットからアクセス可能なコンテナで実行されているか
これらの質問すべてに対する答えが「いいえ」であれば、無視します。「はい」であれば、エスカレートします。
開発者の依存関係や、本番環境にデプロイされないテストパッケージの背後にある推移的な脆弱性をフィルタリングすることも重要です。これにより、多くのノイズを削減でき、誤検知が減り、開発者がソフトウェアの構築に集中できる時間が増えます。
ほとんどのスキャナーは、パッケージがCVEにリストされているかどうかを確認するかもしれません。しかし、実際のコードが脆弱な関数を呼び出しているか、インターネットに公開されたコンテナにバンドルされているか、危険なIAMを持つクラウドリソースで実行されているかを、すべて1つのビューで追跡できるものはごくわずかです。

コード、コンテナ、クラウド構成全体にわたる脆弱性の相関付け
これは非常に重要です。あらゆる場所で何が起こっているかを理解することは、チームの時間を大幅に節約し、不意を突かれる可能性を減らす鍵となります。
これは、この依存関係グラフをパッケージレベルを超えてコンテナ、Infrastructure as Code、クラウド構成へと拡張し、これら全体に到達可能性を重ね合わせることを意味します。
例えば、次のように問いかけることができます。
- この脆弱性は依存関係に影響しますか? はい
- アプリケーションによって実際に呼び出されていますか? いいえ
- パブリックイングレッションを持つデプロイ済みコンテナにバンドルされていますか? いいえ
→ 無視 - この脆弱性は特定のポートが開いている必要がありますか? はい
- その脆弱性はクラウド仮想マシンに存在しますか? はい
- VMで必要なポートは開いていますか? いいえ
→ 無視
自動修復:実際の脆弱性をより迅速に修正する
現実的かつ到達可能な脆弱性として確認された場合、理想的なシナリオは、最小限の安全なアップグレードを特定し、自動的に修正することです。
一部のツールは次のことができます。
- 最小限の安全なアップグレードを自動的に特定する
- セマンティックバージョニングの制約に違反しないことを確認します。
- リグレッションを発生させることなく自動修正します。
これにより、手動での依存関係の追跡が不要になり、夜間の心配事が大幅に減少します。
統合されたセキュリティ戦略の一部として依存関係を管理します。
コード、コンテナ、クラウド設定を1つのグラフに結びつけることで、ノイズを削減し、実際に何が露出しているかを確認できます。誤検知を追いかける必要はありません。
そして、本当に問題がある場合、それは単にフラグが立てられるだけでなく、修正されます。そのため、チームは無意味なアラートを掘り下げる時間を減らし、より多くの時間をリリースに費やすことができます。
Aikidoが開発依存関係のCVEをスキャンする方法については、ドキュメントをご覧ください。オールインワンの脆弱性管理については、こちらをご覧ください。

