SAST 自動脆弱性解決の問題を監視して対応する方法

このランブックをいつ使用するか?

このランブックは、SAST 自動脆弱性解決機能に関連するサービス低下が発生したときに使用します。このような低下は以下を監視することで確認できます:

SAST 自動脆弱性解決

SAST 自動脆弱性解決 機能は、その名の通り、無効化または削除された SAST ルール に関連する脆弱性を自動的に解決するために構築されています。

この機能は、いくつかの構成要素に依存しています:

security-report-schemas のスキーマ定義

セキュリティアナライザースキャンで生成されたレポートは、security-report-schemas リポジトリで JSON スキーマが定義されています。自動脆弱性解決は、security-report-format の一部である特定のスキーマフィールド(primary_identifiers)に依存しています。security-report-format は、sast-report-format を含む他のすべてのセキュリティレポートスキーマの親スキーマです。

analyzers/report パッケージの SARIF モジュール

primary_identifiers フィールドには、アナライザースキャンが対象とするすべての識別子(検出されたものではなく)の完全なリストが含まれています。そのため、レポートに脆弱性が 0 件でも scan.primary_identifiers には完全なリストが含まれる場合があります。このリストは、analyzers/report パッケージの sarif.go モジュールSARIF ファイルを SAST セキュリティレポートに変換する際に生成されます。

Rails アプリケーション内でのドロップされた識別子の処理

gitlab-org/gitlab アプリケーション内でのセキュリティレポートの取り込みでは、IngestReportsServiceスキャン主要識別子を反復処理し、各スキャンタイプに対して ScheduleMarkDroppedAsResolvedService を実行します。これにより MarkDroppedAsResolvedWorker がスケジュールされます。このワーカーは、無効化またはドロップされた識別子(最新のスキャンに存在しない識別子)に一致する識別子を持つすべての脆弱性をループ処理します。

以下は、自動脆弱性解決機能の完全なフローを示す図です。

flowchart TB
code --> analyzer_pipeline

subgraph analyzer_pipeline["analyzer pipeline"]
  direction LR
  analyzer["semgrep analyzer"] --> report_a["noisy-rule-123 dropped"]
  report_a --> report_b["scan.identifiers populated"]
  report_b --> report_c("gl-sast-report.json")
end

analyzer_pipeline --> rails_application

subgraph rails_application["rails application"]
  ingest["IngestReportsService"] --> schedule["ScheduleMarkDroppedAsResolved"]
  schedule --> worker["MarkDroppedAsResolvedWorker"]
end

監視

自動脆弱性解決を監視するための主な情報源が 2 つあります。sentry.io は過去 24 時間の MarkDroppedAsResolvedWorker クラスで発生したエラーをリストアップします。Kibana の SAST Engineering ダッシュボードには、特定のワークを監視し、アップロードされたレポートの量を表示するいくつかのパネルが含まれています。注目すべきパネルとその簡単な説明を以下に示します。

SAST レポートアップロード

アップロードされたセキュリティレポートのファイルサイズの 90 パーセンタイルを 30 分ごとに表示します。これは、一定期間にわたってアップロードされたセキュリティレポートのサイズ(大きいか小さいか)を確認するのに役立ちます。

SAST 失敗ワーカー分布

一定期間にわたって失敗した SAST 関連の sidekiq ワーカーの分布を表示します。

Vulnerabilities::MarkDroppedAsResolvedWorker 実行時間

ワーカーの実行時間の 75 パーセンタイルと 95 パーセンタイルを表示します。

Vulnerabilities::MarkDroppedAsResolvedWorker ジョブステータス

1 時間ごとにジョブステータス別に分けたジョブ実行回数を表示します。これは、一定期間にわたる失敗した実行、重複排除された実行、または成功した実行の量を測定するのに役立ちます。

MarkDroppedAsResolvedWorker 実行上位プロジェクト

ワーカー実行回数が多い上位プロジェクトを表示します。特定の顧客が問題を抱えているかどうかを確認するのに役立ちます。

ログ

さらに、本番ログ で次の 2 つの保存済み検索を確認することをお勧めします:

問題が発生した場合の対処法

  1. 上記の監視セクションを確認します。MarkDroppedAsResolvedWorker に障害が発生していないか確認してください。
  2. ログ を確認し、問題がデータベース書き込み操作(例: 大量のファインディングを解決しようとする場合)中にタイムアウトする可能性があるかどうかを確認してください。
  3. 自動脆弱性解決をオフにする ことを検討してください。

考えられるチェック

  • 自動脆弱性解決に関連するエラーレートの増加がある場合、非常に多くの脆弱性ファインディングを解決しようとした際のこのタイムアウト Issue が原因である可能性があります。

自動脆弱性解決をオフにする方法

primary_identifiers の存在はレポートの取り込みと自動脆弱性解決に必須 です。自動脆弱性解決が期待通りに機能しない場合は、スキャンが生成されたレポートに primary_identifiers を含めないようにすることで、自動解決を停止することを検討してください。そのためには、以下のいずれかのオプションを検討してください:

  1. sarif.go モジュールを更新して、このマージリクエスト で導入された変更を元に戻す。
  2. ScheduleMarkDroppedAsResolvedService#dropped_identifiers メソッドを更新して、primary_identifiers の存在に関わらず早期にリターンするようにする。