Paul McCann

Desde el reporte de vulnerabilidades hasta el borrador de CVE en minutos: cómo Elastic automatiza los avisos de seguridad con IA

Cómo el equipo de seguridad de Elastic construyó un agente de IA con RAG frente a los catálogos CWE y CAPEC de MITRE para redactar avisos CVE a partir de reportes de vulnerabilidades en bruto, incluyendo las configuraciones completas de prompts y rastreadores.

11 min de lecturaGenerative AI, Enablement

El equipo de seguridad de producto de InfoSec de Elastic creó un agente de IA generativa empleando Elastic Agent Builder que redacta avisos completos de seguridad CVE (clasificación CWE, metodología CAPEC, puntaje CVSS y guía de mitigación) directamente a partir de reportes de vulnerabilidades en bruto. El agente emplea RAG contra los catálogos MITRE CWE y CAPEC indexados en Elasticsearch, lo que fundamenta su salida en datos autorizados y previene identificaciones de clasificación alucinadas. ESA-2026-01 ya está en producción como ejemplo de producción que pasó por esta cartera. Así es como lo construimos.

Cómo se redactan manualmente los avisos de seguridad (y por qué es lento)

En Elastic, gestionamos el ciclo de vida de las vulnerabilidades de los productos empleando el PSIRT Service Framework, que define cuatro etapas: descubrimiento, triaje, remediación y divulgación. Cada aviso de seguridad comienza con un reporte de vulnerabilidad recibido durante la fase de descubrimiento, y esos reportes varían mucho en calidad — traducirlos en algo que los clientes puedan consumir es laborioso. Redactamos el aviso de seguridad durante la fase de divulgación, antes de un lanzamiento previsto del producto que contiene la corrección. El aviso se publica entonces como un Aviso de Seguridad Elastic (ESA), con un ID CVE asignado, en el foro Elastic Security Announcements , donde cualquiera puede revisar las vulnerabilidades reveladas y las mitigaciones asociadas.

Cada divulgación también se publica en el Programa CVE, del cual las bases de datos nacionales y regionales posteriores la ingieren automáticamente, incluyendo la Base de datos Nacional de Vulnerabilidades de EE. UU. (NIST), la Base de datos Europea de Vulnerabilidades de la UE (ENISA) y las Notas de Vulnerabilidades de Japón (JPCERT/CC).

Para mantener nuestra producción consistente, seguimos la plantilla estándar de descripción de Vulnerabilidades y Exposiciones Comunes (CVE):

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

El PROBLEMTYPE se identifica mediante una entrada de Enumeración Común de Debilidades (CWE), y el Vector se describe usando una entrada CAPEC (Enumeración y Clasificación de Patrones Comunes de Ataque ).

Sustituyendo el CWE y CAPEC correctos para cada vulnerabilidad, la plantilla se convierte en:

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

La mayor parte del esfuerzo manual se destina a destilar un reporte largo y a menudo técnicamente denso en un aviso conciso y preciso con una evaluación clara del impacto para los clientes. Identificar las clasificaciones correctas de CWE y CAPEC encima hace que el proceso sea enrevesado y prolongado. Aquí es donde la automatización tiene más que ofrecer.

Automatización de borradores de asesoramiento de seguridad con Elastic Agent Builder y RAG

Para agilizar este proceso, nuestro equipo de Seguridad de Producto de InfoSec desarrolló una solución que emplea un LLM para generar automáticamente la frase estandarizada de los avisos de seguridad. Esta solución implica dos pasos clave:

  1. Datos de categorización de vulnerabilidades ingeridos: La alucinación es un modo de fallo bien documentado para los LLM que operan sin conexión a tierra autoritativa. El OWASP Top 10 para Aplicaciones LLM (LLM09) lo lista como una de las categorías de mayor riesgo, y fue la motivación original para la Generación Aumentada por Recuperación. Lo vimos directamente en nuestros primeros experimentos: cuando se les pidió asignar identificaciones CWE y CAPEC sin ayuda, el modelo solía producir entradas que parecían plausibles pero inexistentes. Para evitar esto, empleamos el Elastic Crawler para extraer los sitios web de CWE y CAPEC e ingestionar los datos en dos índices de Elasticsearch: web-crawl-mitre-cwe-software y web-crawl-mitre-capec-software.

  2. Construir el agente de IA generativa: Usamos el Elastic Agent Builder para crear un agente personalizado que emplea un LLM para generar el texto de aviso basado en los datos ingeridos.

Paso 1: Indexación de datos MITRE CWE y CAPEC en Elasticsearch

El primer paso fue incorporar los datos de CWE y CAPEC a Elasticsearch. Para ello, activamos una instancia Elastic Serverless , anotábamos los detalles de la conexión y generamos una clave API. Luego creamos las configuraciones para Elastic Crawler para visitar los sitios web de MITRE y extraer la información relevante. Las mismas configuraciones de rastreadores se ejecutan en un calendario continuo, por lo que los índices se mantienen actualizados mientras MITRE publica nuevas entradas de CWE y CAPEC. Eso mantiene los datos realistas del agente frescos sin intervención manual.

Configuración del crawler CWE

Aquí está la configuración para los datos CWE que se emplea para fundamentar a nuestro agente de IA en datos de vulnerabilidades autoritativos. El rastreador se inicia desde la vista de debilidades del software de CWE, sigue enlaces que coinciden con el patrón de /data/definitions/ y extrae campos estructurados de cada página de debilidad, incluyendo descripciones, mitigaciones, consecuencias y ejemplos observados listos para búsqueda semántica o pipelines 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: .*

Configuración del crawler CAPEC

Aplicamos el mismo enfoque para el catálogo MITRE CAPEC, iniciando desde la vista de patrones de ataque de software y extrayendo campos estructurados de cada página de patrones, incluyendo descripciones de ataques, flujo de ejecución, prerrequisitos, habilidades requeridas y mitigaciones, todo indexado en Elasticsearch junto con los datos CWE.

# 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: .*

Con las configuraciones del rastreador configuradas, ejecutamos los siguientes comandos docker run para iniciar dos contenedores que ejecuten el proceso de rastreo de datos en cada catálogo:

Este comando lanza el rastreador CWE.

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

Este comando lanza el rastreador 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

Ahora que ambos contenedores se ejecutaron con éxito, podemos ver que rastrearon los sitios web e indexado tanto los datos CWE como CAPEC (ejemplo de salida a continuación). Estamos listos para pasar al siguiente paso.

---- 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

Paso 2: Construcción del agente de IA de asesoramiento de seguridad

Con los catálogos CWE y CAPEC indexados en Elasticsearch, el siguiente paso fue construir un agente que pudiera recurrir a ellos para redactar el texto del aviso de seguridad — CWE para la causa raíz, CAPEC para la metodología de ataque. Empleamos el Constructor de Agentes Elásticos para crear un agente personalizado usando Claude Opus, que consistentemente producía textos precisos de advertencia de seguridad y adherencia a las plantillas.

Qué herramientas emplea el agente Elastic Agent Builder

Fundamento en datos de CWE y CAPEC

Tres herramientas forman el núcleo del bucle RAG, permitiendo al agente encontrar y recuperar datos de clasificación autorizados de nuestros catálogos indexados:

  • platform.core.search — Búsqueda en texto completo y estructurada de Elasticsearch. La consulta primaria cuando el agente busca entradas candidatas CWE o CAPEC que coincidan con una vulnerabilidad dada.

  • platform.core.get_document_by_id — recupera un documento completo por índice e ID. Una vez que search redujo los candidatos, esto extrae el registro completo de CWE o CAPEC para que el agente razone en contra de cada campo estructurado — descripción, mitigaciones, ejemplos observados, patrones relacionados — y no solo un fragmento de búsqueda.

  • platform.core.execute_esql — ejecuta un ES|Consulta QL y devuelve resultados tabulares. Se emplea cuando el agente necesita un filtrado más preciso que el que puede ofrecer la búsqueda en texto completo.

Descubrimiento de índices y esquemas

Dos herramientas de detección de índices y esquemas permiten al agente averiguar qué datos están disponibles en lugar de depender de nombres codificados en el prompt:

  • platform.core.list_indices — enumera los índices, alias y flujos de datos a los que el usuario actual puede acceder. Útil cuando el agente necesita confirmar qué índices existen antes de construir una consulta.

  • platform.core.get_index_mapping — recupera mapeos para un índice específico. Permite que el agente vea los campos disponibles antes de escribir una consulta contra él.

  • platform.core.index_explorer — descubrimiento de índices en lenguaje natural. El agente puede preguntar: "¿Qué índice contiene el catálogo CWE?" y recuperar una lista clasificada con mapeos, sin que eso esté incluido en el prompt.

Contexto específico del producto

Cuando el agente rellena las secciones de Configuraciones Afectadas y Soluciones y Mitigaciones del aviso, debe verificar los valores predeterminados de las características y el comportamiento específico del despliegue frente a fuentes autorizadas en lugar de adivinar:

  • platform.core.product_documentation — busca en la documentación del producto Elastic a lo largo de toda la pila.

  • code.search_kibana_code, code.search_kibana_documentation, y code.fetch_kibana_documentation — Acceso a fuentes y documentación específico de Kibana, ejercido cuando el aviso involucra Kibana. Estas dan al agente acceso al código en sí, no solo a la documentación publicada, lo cual es importante para confirmar comportamientos sutiles que la documentación no siempre explica.

Capacidades de recuperación de respaldo

  • documentation.tavily_extract — un receptor defensivo que consigue directamente la página canónica de MITRE. Con un arrastre continuo en el lugar, los catálogos indexados se mantienen actualizados, por lo que esto rara vez se activa; Está ahí para cerciorar de que el agente no sea bloqueado.

Las herramientas no se llaman en orden libre. El prompt indica al agente que agote primero el catálogo indexado — platform.core.search para encontrar candidatos, luego platform.core.get_document_by_id para recuperar el registro completo, antes de recurrir a la herramienta externa de recuperación. Ese orden importa: impide que el agente sustituya silenciosamente contenido externo no verificado por datos contra los que fundamentamos explícitamente.

Cómo ajustamos el prompt del sistema para generar avisos con precisión

El prompt en sí es donde iba la mayor parte de la iteración. Varios comportamientos que incorporamos merecen ser señalados, porque cada uno proviene de algo que vimos hacer al agente y que no queríamos que se repitiera:

  • Verificación de seguridad de la memoria. Al principio de las pruebas, el agente sugirió CWEs por corrupción de memoria (por ejemplo, CWE-119) para vulnerabilidades en nuestros Beats basados en Go, que no se aplican en un lenguaje seguro para memoria. El prompt se ajustó para detectar ahora el lenguaje del componente afectado y prohibir CWEs y CAPECs por corrupción de memoria siempre que el lenguaje sea Go, Rust, Java, TypeScript u otro tiempo de ejecución seguro en memoria.

  • Lista mínima de comprobación para la divulgación. Los avisos deben describir vulnerabilidades sin presentar una prueba de concepto. Una lista de verificación en el prompt escanea el borrador en busca de nombres de funciones, rutas de archivos, rutas de endpoint, nombres de parámetros, números de puerto y detalles de implementación similares, reemplazándolos por equivalentes abstractos ("un componente interno específico", "un campo de entrada suministrado por el usuario") antes de que el borrador se finalice.

  • CAPEC es metodología, no consecuencia. CAPEC puede ser erróneamente elegido como una técnica de impacto ("Denegación de Servicio") en lugar de una técnica de ataque ("Agotamiento de recursos"). El prompt prohíbe explícitamente ese anti-patrón y dice al agente que omita completamente el CAPEC si ninguna entrada describe con precisión la metodología — precisión sobre completitud.

  • "Nunca preguntes, siempre produce." Se indica al agente que redacte un aviso completo a partir de la información que reciba, empleando su propio criterio para los campos que la entrada no cubre, en lugar de volver al operador con preguntas aclaratorias. El operador siempre recibe un borrador completo para revisar.

  • Medidas de puntaje CVSS. Algunos patrones de puntaje no se traducen bien entre productos, como que los remitentes de troncos no deberían ser puntuados Attack Vector: Network a menos que se demuestre explícitamente la explotación directa a Internet. Los niveles de privilegio también se corresponden directamente con los roles integrados de Elastic en el prompt: cualquier rol autenticado como viewer o editor → Privilegios requeridos: Bajos; Roles de nivel administrativo como superuser, kibana_admino ingest_admin → Privilegios requeridos: Alto.

  • Sin servidor. Elastic Cloud Serverless se parchea continuamente, por lo que los avisos para productos con una oferta Serverless incluyen un bloque específico que confirma que la vulnerabilidad ya se solucionó antes de su divulgación pública.

Gestión de vulnerabilidades de primera y tercera parte

No todas las vulnerabilidades son errores de Elastic de primera parte. Algunos son problemas en dependencias de terceros — entornos de ejecución del lenguaje, bibliotecas, paquetes transitivos. El prompt gestiona ambos casos con plantillas diferentes: una ruta de primera parte que se asigna a un par CWE + CAPEC, y una ruta de dependencia basada en CWE-1395 (Dependencia en un componente de terceros vulnerable) que enlaza con el(los) CVE(s) ascendente y el nombre de la dependencia. La ruta de dependencia también da al agente acceso a documentation.tavily_search para consultar el contexto de asesoría upstream, mientras que las vulnerabilidades de primera mano permanecen solo en nuestros catálogos indexados CWE/CAPEC.

Qué produce el agente: borrador de aviso y razonamiento

La respuesta del agente siempre es de dos partes: el borrador del aviso de seguridad y una sección separada de Razonamiento. El razonamiento obliga al agente a justificar cada elección — qué CWE fue seleccionada y por qué, qué CAPEC se eligió (o por qué no se aplicó ninguna), qué privilegios se requieren para explotar el problema y una justificación de una sola frase para cada métrica CVSS. La Lista de Verificación de Divulgación que elimina detalles de implementación del aviso de seguridad público deliberadamente no se aplica a la sección de Razonamiento, por lo que el revisor ve el pensamiento completo del agente, no la versión resumida. Eso da al revisor lo que necesita: lee el Razonamiento, decide si el análisis es correcto y luego toma la decisión en el texto del asesor.

Generador de Avisos de Seguridad Elástica

Construimos el agente en Agent Builder y lo llamamos Elastic Security Advisory Generator, un agente personalizado con las herramientas y el prompt descritos anteriormente. La captura de pantalla de abajo muestra que está configurado en la interfaz de Agent Builder, con el modelo, las herramientas cableadas y el aviso del sistema todos en su lugar:

El extracto a continuación es una versión segura para publicación del prompt que impulsa al agente. Omitimos el prompt completo de producción, que contiene instrucciones específicas de la implementación y detalles operativos internos que no son necesarios para entender el diseño. Para revisarlo, consulta este repositorio público de 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.

El resultado: borradores de asesoría CVE más rápidos y consistentes

Para usar el agente, tomamos un reporte de seguridad (normalmente de nuestro programa de recompensa por errores) y pegamos el contenido en la ventana de conversación del Constructor de Agentes. Ese contenido suele ser libre: una descripción de la vulnerabilidad, el componente y la versión afectados, los pasos de reproducción y la visión del investigador sobre el impacto.

El agente realiza RAG contra los índices CWE y CAPEC, aplica las reglas y salvaguardas del prompt, y produce la salida en dos partes descrita anteriormente: un borrador de aviso de seguridad y una sección de Razonamiento explicando sus elecciones.

Antes de que el borrador sea presentado para su publicación, el revisor de Seguridad de Producto realiza un breve paso de validación:

  • Confirma las selecciones de CWE y CAPEC contra MITRE. La sección de Razonamiento nombra las entradas seleccionadas y por qué. El revisor verifica que cada ID coincida con la entrada oficial de MITRE y que la selección coincida con la vulnerabilidad real.

  • Comproba la cordura del razonamiento de la métrica CVSS. El razonamiento expone una justificación de una frase por métrica. El revisor cuestiona cualquier cosa que no se deduja del reporte.

  • Escanea si comparte más o menos. La lista de verificación de divulgación elimina los detalles de implementación y los reemplaza por un lenguaje abstracto. El revisor revisa el Aviso en busca de detalles que puedan haber colado, y también de cualquier cosa que debería incluir pero no se incluyó. El párrafo debería ser suficiente para entender el problema sin ser una prueba de concepto.

  • Verifica las secciones de Configuraciones y Mitigaciones afectadas. El agente lee la documentación del producto para formular las secciones de "Configuraciones afectadas" y "Mitigaciones". Estas secciones van al equipo de ingeniería que posee el producto para su verificación antes de que se publique el aviso; solo que tienen la certeza sobre los valores predeterminados de las funciones y si una solución alternativa indicada realmente funciona en las versiones afectadas.

El puntaje CVSS se etiqueta explícitamente como borrador en la salida del agente: el equipo de ingeniería responsable del producto y el equipo de Seguridad de Producto de InfoSec aprueban el puntaje final antes de la publicación. En la práctica, la mayoría de los borradores requieren una edición ligera en lugar de una reescritura; El agente acierta con la estructura y el revisor revisa las decisiones y el comportamiento específico del producto.

El ejemplo de resultados que aparece a continuación es lo que el agente produjo para ESA-2026-01, un aviso que publicamos para Metricbeat.

Qué sigue: cerrar el ciclo con Elastic Workflows

Combinar IA generativa con RAG frente a catálogos autoritativos de MITRE convirtió lo que antes era una tarea manual y laboriosa en una parte coherente y rápida de nuestro proceso de asesoramiento. El oleoducto ya está produciendo borradores que van a producción — ESA-2026-01, mostrado arriba, es un ejemplo.

El mayor beneficio es la parte más lenta del proceso antiguo: tomar un reporte largo de vulnerabilidades —a menudo de calidad variable y denso en detalles técnicos— y destilarlo en un asesoramiento conciso y preciso con una evaluación clara del impacto para los clientes. Esa destilación, junto con la plantilla CVE, el mapeo CWE/CAPEC y el razonamiento métrico CVSS, ahora es redactada por el agente. El esfuerzo de nuestro equipo se centra en las partes que requieren juicio humano: comportamiento específico del producto y puntaje de impacto.

El siguiente paso es cerrar el bucle de extremo a extremo. Hoy en día, el agente se invoca manualmente; Un analista pega el reporte de vulnerabilidad en la ventana de conversación. Queremos integrar esto en el propio paso de triaje, usando algo como Elastic Workflows: una vez que una vulnerabilidad se confirma y acepta para su divulgación, el flujo de trabajo invoca automáticamente al agente y produce un borrador de aviso. A partir de ahí, InfoSec e Ingeniería colaboran en un único documento, sustituyendo las entregas manuales entre triaje, redacción y revisión.

Lo que hizo que esto funcionara fue la combinación de datos estables y autoritativos para fundamentar al agente y un estricto paso de revisión. Ambas cosas importan. El mismo patrón puede aplicar a cualquier tarea de redacción estructurada con una plantilla de salida definida y una fuente de datos fiable. Para saber más sobre cómo crear tus propias soluciones de IA generativa con Elastic, consulta la documentación de Elastic Agent Builder.