重複排除について
DefectDojoは、ツールから一括レポートを取り込み、レポートの内容に基づいて1つ以上の検出事項を作成するように設計されています。DefectDojoを使用する際は、同じツールから定期的にレポートを取り込むことがほとんどであるため、重複した検出事項が発生する可能性が非常に高くなります。
ここで役立つのが重複排除機能です。これは、重複した検出事項を自動的に管理できるように設定できるスマートな機能です。
DefectDojoが重複をどのように処理するか
- まず、テスト1. をインポートします。レポートには脆弱性が含まれており、これは検出事項Aとして記録されます。
- その後、同じ脆弱性を含むテスト2をインポートします。これは検出事項Bとして記録され、検出事項Bは検出事項Aの重複としてマークされます。
- さらにその後、同じ脆弱性を含むテスト3をインポートします。これは検出事項Cとして記録され、検出事項Aの重複としてマークされます。
このように重複を作成・マークすることで、DefectDojoは「オリジナル」の脆弱性に関するすべての作業がオリジナルの検出事項ページに集約されるようにし、別々のコンテキストが作られたり、対応が必要な複数の独立した脆弱性が存在するかのような印象をチームに与えたりすることを防ぎます。
どの検出事項がオリジナルになるか
重複排除は、重複チェーンの中で最初に作成された検出事項を常に正規のオリジナルとして扱います。そのため、以前のインポートによる検出事項が、より新しい検出事項の重複に格下げされることはありません。すでに確立されたオリジナルの地位が移ることはありません。
単一のレポート内では、スキャナーが検出事項を列挙する順序によって「勝者」が決まるわけではありません。1回のインポートで作成される検出事項は、内容に基づく安定した順序で作成されるため、同じ重複排除キーで衝突する複数の検出事項を含むレポートは、インポートするたびに同じオリジナルを生成します。同じ結果を再スキャンして再インポートしても、チームが対応してきた検出事項が入れ替わることはありません。
デフォルトでは、重複排除を適用するには、これらのテストが同じ製品の配下にネストされている必要があります。必要に応じて、重複排除の範囲を単一のエンゲージメントにさらに限定することもできます。

重複した検出事項は、デフォルトで非アクティブに設定されます。これは重複した検出事項自体が非アクティブであるという意味ではありません。むしろ、チームが対応・修正すべきアクティブな検出事項が1つだけになるようにするためのものであり、オリジナルの検出事項が緩和済みになると、重複した検出事項も緩和済みになることを意味します。
再インポートにおける重複排除
重複排除と再インポートは似たプロセスですが、検出事項の一致を識別するために異なるアルゴリズムを使用します。
- テストに再インポートすると、再インポートのプロセスは受信した検出事項を確認し、ハッシュコードを比較して、一致するものを破棄します。これらの一致した検出事項は、検出事項としても重複検出事項としても作成されることはありません。
ただし、再インポートの重複排除後に残った検出事項も、引き続き同一ツール重複排除の対象となります。そのため、同一ツール重複排除の範囲をより狭く設定していると、再インポートのパイプライン内で重複が発生することがあります。
例
ここでは、再インポートの重複排除アルゴリズムが同一ツール重複排除アルゴリズムと異なるツールを例に説明します。
| Deduplication Algorithm | Hash Code Fields |
|---|---|
| 再インポート | タイトル、CWE、深刻度、説明、行番号 |
| 同一ツール | タイトル、CWE、深刻度、説明 |
DefectDojo内に、ある行番号を持つ検出事項があったとします。環境を再スキャンしたところ、その脆弱性の行番号が変わりました。同じテストに再インポートします。この場合、再インポートと重複排除の際に何が起こるかを説明します。
- 再インポート中、行番号が異なるため、その検出事項は既存のどの検出事項とも一致しません。そのため、テスト内に新しい検出事項が作成されます。
- 再インポートが完了すると、同一ツール重複排除アルゴリズムが実行されます。この設定では、同一ツール重複排除は行番号を考慮しないため、新しい検出事項は重複としてラベル付けされます。
再インポートは検出事項が記録される前に完全に破棄することがあるため、再インポートの重複排除設定は慎重に調整する必要があります。
重複が適切なのはどのような場合か
重複は、共有されているが個別のテストコンテキストを扱う場合に役立ちます。たとえば、製品が比較が必要な2つの異なるリポジトリのテスト結果をアップロードしている場合、それらのリポジトリ間でどの脆弱性が共有されているかを把握するのに役立ちます。
ただし、DefectDojoが過剰な重複を作成している場合は、パイプラインやインポートプロセスの調整が必要であることを示すサインである可能性もあります。
重複は何を示しているのか
- 同じ脆弱性だが、異なるコンテキストで発見された場合: これは重複した検出事項の適切な使い方です。同じ脆弱性の影響を受けるコンポーネントが多数ある場合、問題の範囲を把握するために、どのコンポーネントが影響を受けているかを知りたいはずです。
- 同じ脆弱性が、同じコンテキストで発見された場合: このケースにはより良い選択肢があります。重複した検出事項が脆弱性について新しいコンテキストを何も提供しない場合や、重複した検出事項を頻繁に無視したり削除したりしている場合は、プロセスを改善できるサインです。たとえば、再インポートを使用すると、CI/CDパイプラインからの受信レポートを効果的に管理できます。重複のたびに全く新しい検出事項オブジェクトを作成する代わりに、再インポートは重複した検出事項を全く作成せずに、受信した重複を記録するだけです。
概要
DefectDojo Open Sourceは、パーサー(テストタイプ)ごとに選択できる4つの重複排除アルゴリズムをサポートしています。
- ツールからの一意のID: スキャナーが提供する一意の識別子を使用します。
- ハッシュコード: 設定されたフィールドのセットを使用してハッシュを計算します。
- ツールからの一意のID、またはハッシュコード: ツールの一意のIDを優先し、一致する一意のIDが見つからない場合はハッシュにフォールバックします。
- レガシー: 複数の条件を持つ従来のアルゴリズムで、Open Sourceバージョンでのみ利用できます。
DefectDojo Proにはさらに機能が追加されています。 追加の2つのアルゴリズムは、単一の製品やエンゲージメント内ではなく、インスタンス内のすべての製品にまたがって一致を判定します。グローバルコンポーネント(コンポーネント名とバージョンによる)とグローバル脆弱性ID(CVE、GHSAなどによる)です。どちらもデフォルトではオフになっており、DefectDojoサポートによって有効化されます。Proでは、ハッシュコードアルゴリズムが検出事項の脆弱性IDとCWEをセットとして扱い、完全一致のセット、いずれかの共有値での一致(_partial)、または一方が他方のサブセットであることによる一致(_subset)が可能です。完全なリスト、セットマッチングのフィールド、およびそれらを管理するルールについては、重複排除のチューニング(Pro)を参照してください。
重複排除の代替手段: 誤検知履歴
意図的に重複排除を行わないインスタンスは、代わりに誤検知履歴を使用できます。これは、同じ製品内で一致する検出事項がすでに誤検知としてトリアージされている場合、受信した検出事項を自動的に誤検知としてマークする機能です。この機能は重複排除と相互排他的であり(DefectDojoは両方を同時に有効にすることを許可していません)、現時点でも実験的機能としてマークされています。
アルゴリズムごとのエンドポイントの評価方法
エンドポイントは、アルゴリズムと設定に応じて、さまざまな方法で重複排除に影響を与えることがあります。
ツールからの一意のID
- 重複排除には
unique_id_from_tool(またはvuln_id_from_tool)を使用します。 - 重複の照合ではエンドポイントは無視されます。
- 検出事項のハッシュは他の機能のために計算されることがありますが、このアルゴリズムの下では重複排除に影響しません。
ハッシュコード
- 重複排除は、対象のパーサーについて
HASHCODE_FIELDS_PER_SCANNERで指定されたフィールドから計算されたハッシュを使用します。 - このハッシュには、
HASH_CODE_FIELDS_ALWAYSのフィールドも含まれます(下記のサービスフィールドのセクションを参照してください)。 - エンドポイントは2つの方法で重複排除に影響を与えることがあります。
- スキャナーのハッシュフィールドに
endpointsが含まれている場合、それらはハッシュの一部となり、それに応じて一致する必要があります。
- スキャナーのハッシュフィールドに
- スキャナーのハッシュフィールドに
endpointsが含まれていない場合、DEDUPE_ALGO_ENDPOINT_FIELDS(OS設定)によって、オプションのエンドポイントベースの照合を有効にできます。設定されている場合:- 空のリスト
[]を設定すると、エンドポイントは完全に無視されます。 - エンドポイント属性のリスト(例:
["host", "port"])を設定します。2つの検出事項間のエンドポイントペアのうち少なくとも1組がリストされたすべての属性で一致する場合、重複排除が発生する可能性があります。
- 空のリスト
ツールからの一意のID、またはハッシュコード
ある検出事項が別の検出事項と同じunique_id_from_tool、または同じhash_codeを持っている場合、それらは重複となります。
検出事項が重複と見なされるには、エンドポイントも一致している必要があります。上記のハッシュコードアルゴリズムを参照してください。
レガシー(Open Sourceのみ)
- 重複排除は、エンドポイントを含む複数の属性を考慮します。
- 静的検出事項と動的検出事項では動作が異なります。
- 静的検出事項: 新しい検出事項はオリジナルのすべてのエンドポイントを含んでいる必要があります。新しい検出事項に追加のエンドポイントがあっても構いません。
- 動的検出事項: エンドポイントは(通常はホストとポートによって)厳密に一致している必要があります。エンドポイントが異なると、重複排除は行われません。
- エンドポイントが存在せず、
file_pathとlineの両方が空である場合、通常は重複排除が行われません。
バックグラウンド処理
- 重複排除は、インポート/再インポート時、およびCeleryを介してバックグラウンドで実行される特定の更新時にトリガーされます。
インポート/再インポートの重複排除実行モード
インポートおよび再インポートでは、重複排除の後処理がどのようにディスパッチされるか、またAPIレスポンスがそれを待つかどうかを制御できます。プロファイルページ(重複排除の実行モード)でユーザーごとに設定するか、インポート/再インポートエンドポイントのdeduplication_execution_modeフィールドでリクエストごとに上書きできます(リクエストの値がプロファイルの設定より優先されます)。
async(デフォルト): 重複排除とその他の後処理はバックグラウンドで実行され、レスポンスは直ちに返されます。これは従来の動作であり、検出事項が重複排除される前にレスポンスが生成されます。async_wait: 後処理は引き続きバックグラウンドにディスパッチされますが、リクエストはレスポンスを返す前に重複排除の完了を待ちます。scan_added通知とレスポンス内の統計は、重複排除後の状態を反映します(重複と判明した検出事項は、新規としてカウント/表示されなくなります)。JIRAへのプッシュ、製品のグレーディング、その他の重複排除以外のタスクは非同期のままで、待機の対象にはなりません。待機時間はDD_DEDUPLICATION_ASYNC_WAIT_TIMEOUT(デフォルト60秒)によって制限されており、時間内にワーカーが処理を開始しない場合、リクエストはハングせずにそのまま応答します。sync: インポートの重複排除は、Webリクエスト内でインラインに実行されます。
インポート/再インポートのレスポンスには、レスポンスが生成された時点で重複排除が完了していたかどうかを示すdeduplication_completeブール値が含まれます(syncの場合、および完了したasync_waitの場合はtrue、asyncの場合はfalseです)。
これは、ユーザーのすべての非同期タスク(通知、JIRAへのプッシュ、製品のグレーディング、重複排除など)をフォアグラウンドで強制実行するグローバルなblock_executionプロファイルフラグとは独立しています。実行モードが設定されていない場合、block_execution=Trueはsyncにフォールバックします。
サービスフィールドとその影響
- デフォルトでは
HASH_CODE_FIELDS_ALWAYS = ["service"]であり、これは検出事項に関連付けられたserviceが、すべてのスキャナーについてハッシュに追加されることを意味します。 - 実際上の影響:
serviceの値以外はまったく同一の2つの検出事項は、異なるハッシュを生成し、ハッシュベースの経路では重複排除されません。- インポート/再インポート時、UIで入力された
Serviceフィールドはパーサーが提供するサービスを上書きすることがあります。これを変更するとハッシュが変わり、その結果、重複排除の結果に影響することがあります。 - サービスが重複排除に影響しないようにしたい場合は、
HASH_CODE_FIELDS_ALWAYSを適切に設定してください(OSのチューニングページを参照してください)。常に含まれるリストからserviceを削除すると、ハッシュに影響しなくなります。
重複検出事項の削除
削除したい重複した検出事項が過剰にある場合は、システム設定のオプションとして重複検出事項の削除を設定できます。
重複検出事項の削除は、最大重複数フィールドと組み合わせることで、DefectDojoが保存する重複検出事項の数を制限できるようにします。このフィールドが有効な場合、DefectDojoは一定数の重複検出事項のみを保持します。
どの重複が削除されるか
オリジナルの検出事項がDefectDojoから自動的に削除されることは決してありませんが、最大重複数のしきい値を超えると、DefectDojoは最も古い重複検出事項を自動的に削除します。
たとえば、最大重複数フィールドを「1」に設定していたとします。
- まず、テスト1. をインポートします。レポートには脆弱性が含まれており、これは検出事項Aとして記録されます。
- その後、同じ脆弱性を含むテスト2をインポートします。これは検出事項Bとして記録され、検出事項Bは検出事項Aの重複としてマークされます。
- さらにその後、同じ脆弱性を含むテスト3をインポートします。これは検出事項Cとして記録され、検出事項Aの重複としてマークされます。この時点で、最大重複数のしきい値を超えたため、検出事項BはDefectDojoから削除されます。
この設定の適用
重複検出事項の削除を適用すると、削除処理が直ちに開始されます。この設定はシステム設定ページで適用できます。詳細については、重複排除の有効化を参照してください。
重複排除のトラブルシューティング
重複排除が想定通りに動作しないことがあります。ここでは、重複排除が正しく機能していない可能性のある例と、考えられる解決策をいくつか紹介します。
| What you see | Most likely cause | What to tune |
|---|---|---|
| 行番号のみが変更された場合に、再インポートが古い検出事項をクローズして新しい検出事項を作成する | 再インポートの照合が不安定なフィールド(行番号など)を使用している | 再インポートの重複排除(安定したIDまたは安定したハッシュフィールドを優先する) |
| 重複しているはずだと思われる複数の検出事項が同じテスト内に作成される | そのツールまたはスコープに対して重複排除の照合が設定されていない | 同一ツールの重複排除(また「重複検出事項の削除」の動作も検討してください) |
| 異なるツール間で重複が作成される | ツール横断照合が無効になっているか、厳しすぎる | ツール横断重複排除(Proのみ)(ハッシュベースの照合) |
| 複数の製品にインポートされた同じSCA依存関係が、重複ではなく別々の検出事項として作成される | 重複排除はデフォルトで製品ごとにスコープされている | グローバルコンポーネント重複排除(Proのみ)(SCAツール向けに有効化する)、またはロケーションデータモデルの下でグローバルロケーション重複排除(Proのみ)(共有ロケーションで照合する) |
| 複数の製品にインポートされた同じURL / Webの検出事項が、重複ではなく別々の検出事項として作成される | 重複排除はデフォルトで製品ごとにスコープされており、グローバルコンポーネントはコンポーネントのみを照合する | グローバルロケーション重複排除(Proのみ)(製品をまたいでDAST/URLの検出事項を照合する) |
| テストをまたいで同じ検出事項の過剰な重複が作成される | アセット階層が正しく設定されていない | 継続的なテストには再インポートの利用を検討してください |
自動重複排除が、本来同じグループにまとめるべきだと考える検出事項を見逃した場合は、検出事項の表示ページから手動でリンクできます。関連する検出事項を見つけて手動で重複としてマークする方法については、類似検出事項(Open Source | Pro)を参照してください。