Paul McCann

脆弱性レポートからCVEドラフトまで数分で:ElasticがAIでセキュリティアドバイザリを自動化する方法

Elasticのセキュリティチームが、MITREのCWEおよびCAPECカタログに対してRAGを使用してAIエージェントを構築し、完全なプロンプトとクローラー設定を含む生の脆弱性レポートからCVEアドバイザリを作成した方法。

11分で読めますGenerative AI, Enablement

Elastic社の情報セキュリティ製品セキュリティチームは、Elastic Agent Builderを使用して、生の脆弱性レポートから直接、完全なCVEセキュリティアドバイザリ(CWE分類、CAPEC手法、CVSSスコアリング、および緩和策ガイダンス)を作成する生成型AIエージェントを構築しました。このエージェントは、Elasticsearchにインデックス化されたMITRE CWEおよびCAPECカタログに対してRAGを使用し、出力を信頼できるデータに基づいて作成し、誤った分類IDの発生を防ぎます。ESA-2026-01は、このパイプラインを経由した出力の一例として、既に生産段階に入っています。これがその構築方法です。

セキュリティ勧告がどのように手動で作成されるのか(そしてなぜ時間がかかるのか)

Elasticでは、製品の脆弱性のライフサイクルをPSIRTサービスフレームワークを使用して管理しています。このフレームワークは、発見、トリアージ、修復、開示という4つの段階を定義しています。セキュリティアドバイザリはそれぞれ、発見段階で受け取った脆弱性レポートから始まりますが、これらのレポートの質は大きく異なるため、顧客が理解できる形に変換するには時間がかかります。セキュリティ勧告は、修正プログラムを含む予定の製品リリースに先立ち、情報公開段階で作成します。その後、この勧告はElastic Security Advisory(ESA)として、CVE IDが割り当てられた状態でElastic Security Announcementsフォーラムに公開され、誰でも公開された脆弱性とそれに関連する対策を確認できます。

各開示情報はCVEプログラムにも公開され、そこから下流の国や地域のデータベース(米国国立標準技術研究所(NIST)、欧州連合の欧州脆弱性データベース(ENISA)、日本の日本脆弱性ノート(JPCERT/CC)など)に自動的に取り込まれる。

出力の一貫性を保つため、当社は標準的な共通脆弱性識別子(CVE)の説明テンプレートに従っています。

[PROBLEMTYPE] in [COMPONENT] in [VENDOR] [PRODUCT] [VERSION] on [PLATFORMS] allows [ATTACKER] to [IMPACT] via [VECTOR]

PROBLEMTYPEは共通脆弱性列挙(CWE)エントリを使用して識別され、Vectorは共通攻撃パターン列挙および分類(CAPEC)エントリを使用して記述されます。

各脆弱性に対して適切なCWEとCAPECを代入すると、テンプレートは次のようになります。

[Common Weakness Enumeration] in [COMPONENT] in [VENDOR] [PRODUCT] [VERSION] on [PLATFORMS] allows [ATTACKER] to [IMPACT] via [Common Attack Pattern Enumeration and Classification]

手作業の大部分は、長くて技術的に難解な脆弱性レポートを、顧客にとって明確な影響評価を含む簡潔で正確なアドバイスにまとめることに費やされます。さらに、適切なCWEおよびCAPEC分類を特定することも、プロセスを複雑で時間のかかるものにしている。自動化が最も効果を発揮するのはまさにこの分野だ。

Elastic Agent BuilderとRAGを使用してセキュリティアドバイザリ草案を自動化する

このプロセスを効率化するため、当社の情報セキュリティ製品セキュリティチームは、LLM(論理言語モデル)を使用してセキュリティ勧告用の標準化された文章を自動的に生成するソリューションを開発しました。この解決策には、2つの重要なステップが含まれます。

  1. 脆弱性分類データの取り込み:権威ある根拠なしに動作するLLMにとって、幻覚はよく知られた障害モードです。OWASP Top 10 for LLM Applications (LLM09) では、これをトップリスクカテゴリとして挙げており、これが検索拡張生成の当初の動機でした。初期の実験で、私たちはそれを直接確認しました。CWEとCAPECのIDを補助なしで割り当てるように求められた場合、モデルはしばしばもっともらしく見えるものの、実際には存在しないエントリを生成しました。これを防ぐために、 Elastic Crawlerを使用して CWE と CAPEC の Web サイトをスクレイピングし、データを 2 つの Elasticsearch インデックスweb-crawl-mitre-cwe-softwareweb-crawl-mitre-capec-softwareに取り込みました。

  2. 生成型AIエージェントの構築: Elastic Agent Builderを使用して、取り込んだデータに基づいてLLMを使用してアドバイステキストを生成するカスタムエージェントを作成しました。

ステップ1:MITRE CWEおよびCAPECデータをElasticsearchにインデックス化する

最初のステップは、CWEとCAPECのデータをElasticsearchに取り込むことでした。そのため、 Elastic Serverlessインスタンスを起動し、接続の詳細を記録し、APIキーを生成しました。次に、 Elastic CrawlerがMITREのウェブサイトにアクセスして関連情報を抽出するための設定を作成しました。同じクローラー構成が継続的に実行されるため、MITREが新しいCWEおよびCAPECエントリを公開するたびに、インデックスは常に最新の状態に保たれます。これにより、エージェントの地上データは手動介入なしに常に最新の状態に保たれます。

CWEクローラー構成

以下は、当社のAIエージェントを信頼できる脆弱性データに基づいて動作させるために使用されるCWEデータの構成です。CWEのソフトウェア脆弱性ビューからクローラーシードを取得し、 /data/definitions/パターンに一致するリンクをたどり、各脆弱性ページから構造化されたフィールド(説明、緩和策、影響、観測された例など)を抽出し、セマンティック検索やRAGパイプラインで使用できる状態にします。

# CWE Crawler Configuration (crawl-config-mitre-cwe.yml)

output_sink: elasticsearch
output_index: web-crawl-mitre-cwe-software

elasticsearch:
  host: "YOUR_ELASTIC_URL"
  port: 443
  api_key: "YOUR_API_KEY"
  pipeline_enabled: false

domains:
  - url: https://cwe.mitre.org
    seed_urls:
      - https://cwe.mitre.org/data/definitions/699.html

    extraction_rulesets:
      - url_filters:
          - type: "regex"
            pattern: "/data/definitions/[0-9]+\\.html"
        rules:
          # 1. Capture the Full URL in a custom field
          - action: "extract"
            field_name: "cwe_source_url"
            selector: ".*" # Match everything in the URL
            join_as: "string"
            source: "url"

          # 2. Extract Just the ID Number from the URL (e.g., 79)
          - action: "extract"
            field_name: "cwe_id"
            selector: "definitions/([0-9]+)" # Capturing group isolates the digits
            join_as: "string"
            source: "url"

          # 3. Full Title
          - action: "extract"
            field_name: "cwe_full_title"
            selector: "h2"
            join_as: "string"
            source: "html"

          # 4. Description Section
          - action: "extract"
            field_name: "description"
            selector: "#Description .detail"
            join_as: "string"
            source: "html"

          # 5. Extended Description
          - action: "extract"
            field_name: "extended_description"
            selector: "#Extended_Description .detail"
            join_as: "string"
            source: "html"

          # 6. Alternate Terms (Array)
          - action: "extract"
            field_name: "alternate_terms"
            selector: "#Alternate_Terms .detail tr"
            join_as: "array"
            source: "html"

          # 7. Common Consequences (Array)
          - action: "extract"
            field_name: "common_consequences"
            selector: "#Common_Consequences .detail tr"
            join_as: "array"
            source: "html"

          # 8. Potential Mitigations (Array)
          - action: "extract"
            field_name: "potential_mitigations"
            selector: "#Potential_Mitigations .detail tr"
            join_as: "array"
            source: "html"

          # 9. Background Details
          - action: "extract"
            field_name: "background_details"
            selector: "#Background_Details .detail"
            join_as: "string"
            source: "html"

          # 10. Modes of Introduction (Array)
          - action: "extract"
            field_name: "modes_of_introduction"
            selector: "#Modes_Of_Introduction .detail tr"
            join_as: "array"
            source: "html"

          # 11. Applicable Platforms (Array)
          - action: "extract"
            field_name: "applicable_platforms"
            selector: "#Applicable_Platforms .detail tr"
            join_as: "array"
            source: "html"

          # 12. Likelihood of Exploit
          - action: "extract"
            field_name: "likelihood_of_exploit"
            selector: "#Likelihood_Of_Exploit .detail"
            join_as: "string"
            source: "html"

          # 13. Demonstrative Examples
          - action: "extract"
            field_name: "demonstrative_examples"
            selector: "#Demonstrative_Examples .detail"
            join_as: "string"
            source: "html"

          # 14. Observed Examples (Array)
          - action: "extract"
            field_name: "observed_examples"
            selector: "#Observed_Examples .detail tr"
            join_as: "array"
            source: "html"

          # 15. Taxonomy Mappings (Array)
          - action: "extract"
            field_name: "taxonomy_mappings"
            selector: "#Taxonomy_Mappings .detail tr"
            join_as: "array"
            source: "html"

          # 16. Related Attack Patterns (Array)
          - action: "extract"
            field_name: "related_attack_patterns"
            selector: "#Related_Attack_Patterns .detail tr"
            join_as: "array"
            source: "html"

          # 17. References (Array)
          - action: "extract"
            field_name: "references"
            selector: "#References .detail tr"
            join_as: "array"
            source: "html"

    crawl_rules:
      - policy: allow
        type: begins
        pattern: "/data/definitions/"
      - policy: deny
        type: contains
        pattern: "/history"
      - policy: deny
        type: regex
        pattern: .*

CAPECクローラーの設定

MITRE CAPECカタログに対しても同様のアプローチを採用し、ソフトウェア攻撃パターンビューからデータを取得し、各パターンページから攻撃の説明、実行フロー、前提条件、必要なスキル、緩和策などの構造化されたフィールドを抽出し、CWEデータとともにElasticsearchにインデックス化します。

# CAPEC Crawler Configuration (crawl-config-mitre-capec-software.yml)
output_sink: elasticsearch
output_index: web-crawl-mitre-capec-software

elasticsearch:
  host: "YOUR_ELASTIC_URL"
  port: 443
  api_key: "YOUR_API_KEY"
  pipeline_enabled: false

domains:
  - url: https://capec.mitre.org
    seed_urls:
      - https://capec.mitre.org/data/definitions/513.html # The "Software" Category View

    extraction_rulesets:
      - url_filters:
          - type: "regex"
            pattern: "/data/definitions/[0-9]+\\.html"
        rules:
          # 1. Capture the Full Source URL
          - action: "extract"
            field_name: "capec_source_url"
            selector: ".*"
            join_as: "string"
            source: "url"

          # 2. CAPEC ID (isolates just the number from the URL, e.g., 63)
          - action: "extract"
            field_name: "capec_id"
            selector: "definitions/([0-9]+)"
            join_as: "string"
            source: "url"

          # 3. Full Title (e.g., CAPEC-63: Cross-Site Scripting)
          - action: "extract"
            field_name: "capec_full_title"
            selector: "h2"
            join_as: "string"
            source: "html"

          # 4. Description Section
          - action: "extract"
            field_name: "description"
            selector: "#Description .indent"
            join_as: "string"
            source: "html"

          # 5. Likelihood Of Attack
          - action: "extract"
            field_name: "likelihood_of_attack"
            selector: "#Likelihood_Of_Attack .detail"
            join_as: "string"
            source: "html"

          # 6. Typical Severity
          - action: "extract"
            field_name: "typical_severity"
            selector: "#Typical_Severity .detail"
            join_as: "string"
            source: "html"

          # 7. Relationships (Array of table rows)
          - action: "extract"
            field_name: "relationships"
            selector: "#Relationships .tabledetail tr"
            join_as: "array"
            source: "html"

          # 8. Execution Flow
          - action: "extract"
            field_name: "execution_flow"
            selector: "#Execution_Flow .detail"
            join_as: "string"
            source: "html"

          # 9. Prerequisites
          - action: "extract"
            field_name: "prerequisites"
            selector: "#Prerequisites .detail tr"
            join_as: "array"
            source: "html"

          # 10. Skills Required
          - action: "extract"
            field_name: "skills_required"
            selector: "#Skills_Required .detail tr"
            join_as: "array"
            source: "html"

          # 11. Resources Required
          - action: "extract"
            field_name: "resources_required"
            selector: "#Resources_Required .detail tr"
            join_as: "array"
            source: "html"

          # 12. Mitigations
          - action: "extract"
            field_name: "mitigations"
            selector: "#Mitigations .detail tr"
            join_as: "array"
            source: "html"

          # 13. Example Instances
          - action: "extract"
            field_name: "example_instances"
            selector: "#Example_Instances .detail"
            join_as: "string"
            source: "html"

          # 14. Related Weaknesses (CWE Mappings)
          - action: "extract"
            field_name: "related_weaknesses"
            selector: "#Related_Weaknesses .tabledetail tr"
            join_as: "array"
            source: "html"

          # 15. Taxonomy Mappings
          - action: "extract"
            field_name: "taxonomy_mappings"
            selector: "#Taxonomy_Mappings .tabledetail tr"
            join_as: "array"
            source: "html"

          # 16. References
          - action: "extract"
            field_name: "references"
            selector: "#References .detail tr"
            join_as: "array"
            source: "html"

    crawl_rules:
      # Allow the seed page and any pattern definition
      - policy: allow
        type: begins
        pattern: "/data/definitions/"

      # Deny navigational noise
      - policy: deny
        type: contains
        pattern: "/history"
      - policy: deny
        type: regex
        pattern: .*

クローラーの設定が完了したら、各カタログでデータクロール処理を実行するための2つのコンテナを起動するために、 docker runのコマンドを実行しました。

このコマンドはCWEクローラーを起動します。

docker run --rm \
  -v "$(pwd)":/config \
  -it docker.elastic.co/integrations/crawler:latest jruby \
  bin/crawler crawl /config/crawl-config-mitre-cwe.yml

このコマンドはCAPECクローラーを起動します。

docker run --rm \
  -v "$(pwd)":/config \
  -it docker.elastic.co/integrations/crawler:latest jruby \
  bin/crawler crawl /config/crawl-config-mitre-capec-software.yml

両方のコンテナが正常に実行されたので、ウェブページをクロールし、CWEとCAPECの両方のデータをインデックス化できたことがわかります(出力例を以下に示します)。次のステップに進む準備が整いました。

---- Crawl Stats ----
- Pages visited: 575
- URLs allowed: 574
- URLs denied
  - Already seen: 2817
  - Domain filter: 9936
- Crawl duration (seconds): 146
- Crawling time (seconds): 106.245
- Average response time (seconds): 0.18477391304347826

---- Elasticsearch Ingestion Stats ----
- Completed
  - Documents upserted: 574
  - Volume (bytes): 9626811
- Failed
  - Number of documents that failed to index: 0
  - Volume (bytes): 0

ステップ2:セキュリティアドバイザリAIエージェントの構築

ElasticsearchにCWEとCAPECのカタログをインデックス化した後、次のステップは、それらを利用してセキュリティ勧告文を作成できるエージェントを構築することでした。CWEは根本原因、CAPECは攻撃手法に関する情報を提供します。私たちはElastic Agent Builderを使用してClaude Opusを用いたカスタムエージェントを作成しました。これにより、常に正確なセキュリティアドバイザリのテキストとテンプレートへの準拠が得られました。

Elastic Agent Builderエージェントが使用するツールは何ですか?

CWEとCAPECのデータに基づく

RAGループの中核を成す3つのツールは、エージェントがインデックス付きカタログから信頼できる分類データを検索・取得することを可能にする。

  • platform.core.search — Elasticsearchの全文検索および構造化検索。エージェントが特定の脆弱性に一致する候補となるCWEまたはCAPECエントリを検索する際の、主要な検索対象。

  • platform.core.get_document_by_id — インデックスとIDによって文書全体を取得します。search候補を絞り込むと、完全な CWE または CAPEC レコードが取得され、エージェントは検索スニペットだけでなく、説明、緩和策、観測された例、関連パターンなど、すべての構造化フィールドに対して推論を行います。

  • platform.core.execute_esql — ES|QLクエリを実行し、表形式の結果を返します。エージェントが全文検索よりもさらに精度の高いフィルタリングを必要とする場合に使用します。

インデックスとスキーマの検出

2つのインデックスおよびスキーマ検出ツールにより、エージェントはプロンプト内のハードコードされた名前に頼るのではなく、利用可能なデータを把握できます。

  • platform.core.list_indices — 現在のユーザーがアクセスできるインデックス、エイリアス、およびデータストリームを一覧表示します。エージェントがクエリを作成する前に、どのようなインデックスが存在するかを確認する必要がある場合に役立ちます。

  • platform.core.get_index_mapping — 特定のインデックスのマッピングを取得します。エージェントがクエリを作成する前に、利用可能なフィールドを確認できるようにします。

  • platform.core.index_explorer — 自然言語によるインデックス発見。エージェントは「CWEカタログはどのインデックスに格納されていますか?」と尋ねることができます。そして、プロンプトにマッピング情報が組み込まれていない状態で、マッピング情報を含むランキングリストを取得します。

製品固有のコンテキスト

エージェントがアドバイザリの「影響を受ける構成」および「解決策と緩和策」セクションに情報を入力する際には、推測するのではなく、信頼できる情報源に基づいて機能のデフォルト設定や展開固有の動作を検証する必要があります。

  • platform.core.product_documentation — Elastic製品に関するドキュメントをスタック全体にわたって検索します。

  • code.search_kibana_codecode.search_kibana_documentation 、およびcode.fetch_kibana_documentation — Kibana固有のソースおよびドキュメントへのアクセス。勧告がKibanaに関連する場合に実行されます。これらによって、エージェントは公開されているドキュメントだけでなく、コード自体にもアクセスできるようになります。これは、ドキュメントには必ずしも明記されていない微妙な動作を確認する上で重要です。

フォールバック取得機能

  • documentation.tavily_extract — MITREの正規ページを直接取得する、防御的なバックストップ。継続的なクロールが実施されている場合、インデックス付きカタログは常に最新の状態に保たれるため、この処理はめったに発生しません。これは、エージェントがブロックされないようにするためのものです。

ツールは自由な順序で呼び出されるわけではありません。このプロンプトは、エージェントに対し、まずインデックス付きカタログを徹底的に検索し( platform.core.searchで候補を検索、次にplatform.core.get_document_by_idで完全なレコードを取得)、それでも解決しない場合は外部検索ツールにフォールバックするように指示します。その順序付けは重要です。なぜなら、エージェントが、私たちが明示的に根拠としたデータの代わりに、検証されていない外部コンテンツを密かに置き換えることを防ぐからです。

正確なアドバイス生成のためにシステムプロンプトをどのように調整したか

試行錯誤の大部分は、プロンプト自体に費やされた。私たちが組み込んだいくつかの動作は特筆に値する。なぜなら、それぞれがエージェントが行った動作のうち、私たちが繰り返してほしくないものから着想を得たものだからだ。

  • メモリ安全性の検証。テストの初期段階で、エージェントは、Go言語ベースのBeatsにおける脆弱性に対して、メモリ破損に関するCWE(例:CWE-119)を提案しましたが、これはメモリセーフな言語には適用されません。プロンプトが調整され、影響を受けるコンポーネントの言語を検出し、その言語がGo、Rust、Java、TypeScript、またはその他のメモリセーフなランタイムである場合は、メモリ破損CWEおよびCAPECを禁止するようになりました。

  • 最低限の情報開示チェックリスト勧告では、概念実証を作成することなく、脆弱性について説明するべきである。プロンプト内のチェックリストは、ドラフトをスキャンして関数名、ファイルパス、エンドポイントパス、パラメータ名、ポート番号、および同様の実装の詳細を検出し、ドラフトが最終化される前に、それらを抽象的な同等のもの(「特定の内部コンポーネント」、「ユーザーが提供する入力フィールド」)に置き換えます。

  • CAPECは方法論であって、結果ではない。CAPECは、攻撃手法(「リソース枯渇」)ではなく、影響(「サービス拒否」)として誤って選択される可能性がある。この指示では、そのアンチパターンを明確に禁止しており、方法論を正確に記述したエントリがない場合は、エージェントにCAPECを完全に省略するように指示しています。つまり、完全性よりも正確性が優先されます。

  • 「決して求めず、常に生み出せ。」担当者は、受け取った情報に基づいて完全なアドバイスを作成するよう指示されており、入力情報でカバーされていない分野については、オペレーターに確認の質問をするのではなく、自身の判断に基づいて作成することになっている。オペレーターは常に完全な草稿を受け取り、確認する。

  • CVSS採点基準。一部のスコアリングパターンは製品間でうまく適用できない。例えば、ログシッパーは、インターネットに接続された悪用が明確に実証されない限り、 Attack Vector: Network評価されるべきではない。権限レベルは、プロンプト内の Elastic の組み込みロールに直接対応しています。認証されたロールviewerまたはeditorなど) → 必要な権限: 低。管理者レベルのロール ( superuserkibana_admin 、またはingest_adminなど) → 必要な権限: 高。

  • サーバーレス。Elastic Cloud Serverlessは継続的にパッチを適用するため、サーバーレス機能を提供する製品に関するアドバイザリには、脆弱性が一般公開前に既に修正済みであることを確認する特定のブロックが含まれています。

自社および第三者の脆弱性への対処

すべての脆弱性がElastic社自身のバグであるとは限りません。中には、サードパーティの依存関係(言語ランタイム、ライブラリ、推移的パッケージなど)に問題があるものもあります。プロンプトは、異なるテンプレートを使用して両方のケースを処理します。1つはCWE + CAPECのペアにマッピングされるファーストパーティパス、もう1つはCWE-1395(脆弱なサードパーティコンポーネントへの依存)をキーとする依存関係パスで、上流のCVEと依存関係名にリンクします。依存関係パスにより、エージェントはdocumentation.tavily_searchにアクセスして上流のアドバイザリコンテキストを取得できますが、ファーストパーティの脆弱性は、インデックス化されたCWE/CAPECカタログのみに保持されます。

エージェントが出力するもの:助言案と理由

エージェントの回答は常に2つの部分から構成されます。1つはセキュリティ勧告案、もう1つは独立した理由説明セクションです。推論機能では、エージェントは各選択を正当化する必要があります。どのCWEが選択されたのか、その理由、どのCAPECが選択されたのか(または適用されない理由)、問題を悪用するために必要な権限、そして各CVSS指標に対する1文の正当化です。公開セキュリティ勧告から実装の詳細を削除する開示チェックリストは、意図的に推論セクションには適用されないため、レビュー担当者はエージェントの思考過程全体を把握でき、抽象化されたバージョンを見ることはありません。これにより、審査担当者は必要なものをすべて得ることができます。つまり、審査担当者は理由説明を読み、分析が妥当かどうかを判断し、その上で助言文について最終的な判断を下すのです。

弾性セキュリティアドバイザリジェネレーター

私たちはエージェントビルダーでエージェントを構築し、「 Elastic Security Advisory Generator」と名付けました。これは、上記で説明したツールとプロンプトを備えたカスタムエージェントです。以下のスクリーンショットは、エージェントビルダーUIでモデル、接続されたツール、システムプロンプトがすべて設定された状態を示しています。

以下に示す抜粋は、エージェントを動作させるプロンプトの、公開しても問題ないバージョンです。設計を理解する上で不要な、実装固有の手順や内部的な運用詳細が含まれているため、完全な本番環境向けプロンプトは省略しました。内容を確認するには、こちらの公開GitHubリポジトリをご覧ください。

## ROLE & OBJECTIVE

You are the Elastic Security Advisory Generator. Your task is to classify Elastic-specific vulnerabilities against approved industry taxonomies and draft a consistent public-facing security advisory.

Your goal is to produce a concise advisory that is accurate, reviewable, and grounded in authoritative source material, while minimizing unnecessary disclosure of exploit-enabling implementation detail.

---

## CORE BEHAVIOR

Produce a complete first draft from the information available in the vulnerability report.

- Use user-provided facts when they are present.
- Use approved internal reference data and product documentation to fill in missing context.
- Use best-effort judgment for non-critical narrative fields that are not explicitly provided.
- Leave placeholders only for identifiers that may genuinely be unavailable at draft time, such as the advisory number, CVE number, or final fixed version.

---

## INTAKE

Extract as many of the following fields as possible from the report:

1. Product name
2. Advisory identifier
3. CVE identifier
4. Fixed version or release
5. Affected versions
6. Deployment or configuration context

Include a Serverless remediation note only when the affected product has a Serverless offering or when applicability has been separately confirmed.

---

## GROUNDING AND SAFETY RULES

1. Use authoritative taxonomy data and product documentation as the primary sources of truth.
2. Prefer grounded retrieval over model inference when choosing weakness and attack-pattern classifications.
3. Keep the public advisory focused on what the issue is, who is affected, and how customers should respond.
4. Remove or generalize details that would make exploitation easier, including specific internal component names, file paths, endpoint paths, parameter names, port numbers, stack traces, and infrastructure identifiers.
5. For dependency vulnerabilities, include upstream dependency and CVE context only when that information is necessary to explain exposure.

---

## CLASSIFICATION GUARDRAILS

Before selecting taxonomy entries, identify the likely implementation language of the affected component.

- If the component is implemented in a memory-safe language, avoid memory-corruption classifications unless the report clearly indicates native-code involvement or low-level memory-corruption behavior.
- Select weakness classifications based on root cause.
- Select attack-pattern classifications based on methodology, not impact.
- If no attack-pattern entry accurately describes the method, omit it rather than forcing a weak match.

---

## MITIGATIONS AND SEVERITY

- Confirm affected configurations, deployment defaults, and workaround viability against product documentation before stating them.
- Distinguish between self-managed and hosted or managed deployment guidance when the mitigations differ.
- Produce only a draft CVSS assessment and justify each metric from the report details rather than from the vulnerability label alone.

---

## OUTPUT FORMAT

Return two clearly separated sections:

1. The Advisory
  - Subject line
  - One-line summary
  - Affected versions
  - Affected configurations
  - Solutions and mitigations
  - Indicators of compromise, when applicable
  - Serverless note, when applicable
  - Severity, CVE, problem type, and impact

2. Reasoning
  - Language assessment and safety guardrails applied
  - Rationale for selected taxonomy entries
  - Privilege assumptions
  - Draft CVSS metric reasoning

The public-facing advisory should stay high level. The Reasoning section may retain the additional context needed for internal validation.

その結果、より迅速で一貫性のあるCVE勧告案が作成された。

エージェントを使用するには、セキュリティレポート(通常はバグ報奨金プログラムからのレポート)を取得し、その内容をエージェントビルダーの会話ウィンドウに貼り付けます。その内容は通常、自由形式で、脆弱性の説明、影響を受けるコンポーネントとバージョン、再現手順、そして研究者による影響の見解などが含まれる。

エージェントは、CWEおよびCAPECインデックスに対してRAGを実行し、プロンプト内のルールとガードレールを適用して、上記で説明した2部構成の出力、すなわちセキュリティ勧告の草案と、その選択を説明する推論セクションを生成します。

草案が公表される前に、製品セキュリティ担当者は簡単な検証プロセスを実施します。

  • CWEとCAPECの選定結果をMITREと照合して確認してください。「理由」のセクションでは、選択された項目とその理由を記載します。レビュー担当者は、各IDが公式のMITREエントリと一致していること、および選択内容が実際の脆弱性と一致していることを確認します。

  • CVSS指標の根拠を検証する。理由説明では、各指標について1文でその根拠を示します。査読者は、報告書の内容から導き出されないあらゆる事柄に異議を唱える。

  • 過剰共有や過少共有がないかスキャンする。情報開示チェックリストは、実装の詳細を削除し、抽象的な言葉に置き換える。レビュー担当者は、勧告書を精査し、見落とされた可能性のある具体的な事項や、含めるべきであるにもかかわらず含まれていない事項がないかを確認する。その段落は、概念実証をすることなく、問題点を理解するのに十分な内容であるべきです。

  • 影響を受ける構成と緩和策のセクションを確認してください。エージェントは製品ドキュメントを読み込み、「影響を受ける構成」と「緩和策」のセクションを作成します。これらのセクションは、勧告が公開される前に、製品を所有するエンジニアリングチームに送られ、検証が行われます。機能のデフォルト設定や、記載されている回避策が影響を受けるリリースで実際に機能するかどうかについて、確かな情報を持っているのは彼らだけだからです。

CVSSスコアはエージェントの出力において明示的に「ドラフト」と表示され、製品を担当するエンジニアリングチームと情報セキュリティ製品セキュリティチームが公開前に最終スコアを承認します。実際には、ほとんどの草稿は書き直しではなく、軽微な編集で済む。エージェントは構成を正しく整え、レビュー担当者は判断事項や製品固有の動作を確認する。

以下に示す出力例は、Metricbeat向けに公開した勧告ESA-2026-01に対してエージェントが生成したものです。

次のステップ:Elastic Workflowsでループを閉じる

生成型AIとRAGを組み合わせ、権威あるMITREカタログと照合することで、従来は手作業で時間のかかる作業だったものが、一貫性があり迅速なアドバイザリープロセスの一部へと変わりました。このパイプラインは既に製品版となるドラフトを作成しており、上に示したESA-2026-01はその一例である。

最大の成果は、従来のプロセスで最も時間がかかっていた部分、つまり、品質にばらつきがあり、技術的な詳細がぎっしり詰まった長文の脆弱性レポートを、顧客にとって明確な影響評価を伴う簡潔かつ正確なアドバイスにまとめる作業が不要になった点にある。その抽出作業は、CVEテンプレート作成、CWE/CAPECマッピング、CVSSメトリック推論とともに、現在エージェントによって作成されています。私たちのチームは、人間の判断が必要な部分、つまり製品固有の挙動や影響度評価に力を注いでいます。

次のステップは、ループを最初から最後まで閉じることです。現在、エージェントは手動で起動され、アナリストが脆弱性レポートを会話ウィンドウに貼り付けます。Elastic Workflowsのようなものを使って、これをトリアージのステップ自体に組み込みたいと考えています。脆弱性が確認され、開示が承認されると、ワークフローが自動的にエージェントを起動し、勧告案を作成します。そこから、情報セキュリティ部門とエンジニアリング部門が単一の文書で共同作業を行い、トリアージ、ドラフト作成、レビュー間の手作業による引き継ぎをなくします。

この手法が成功した要因は、エージェントの基準となる安定した信頼できるデータと、厳格な審査手順の組み合わせにあった。どちらも重要です。同じパターンは、明確な出力テンプレートと信頼できるデータソースを備えた、あらゆる構造化された文書作成作業に適用できます。Elasticを使用して独自の生成型AIソリューションを構築する方法について詳しく知りたい場合は、 Elastic Agent Builderのドキュメントを参照してください。

この記事を共有する