"""
Tool 3: summarize_cve_risk
Genera un resumen del riesgo en lenguaje orientado a equipos SOC/Blue Team.
"""
import logging
from typing import Optional
from ..api.circl_client import get_client
from ..utils.formatters import format_risk_summary
logger = logging.getLogger(__name__)
async def summarize_cve_risk(
cve_id: str,
context: Optional[str] = None
) -> str:
"""
Resumen de riesgo para SOC/Blue Team.
Args:
cve_id: Identificador CVE
context: Contexto del activo afectado (ej. "servidor web público")
Returns:
String formateado con el análisis de riesgo
Raises:
ValueError: Si el CVE ID es inválido
Exception: Para otros errores
"""
logger.info(f"Tool summarize_cve_risk called for {cve_id}, context: {context}")
# Validación
if not cve_id or not isinstance(cve_id, str):
raise ValueError("CVE ID debe ser un string no vacío")
cve_id = cve_id.strip().upper()
if not cve_id.startswith("CVE-"):
raise ValueError(
f"CVE ID inválido: '{cve_id}'. "
"Formato esperado: CVE-YYYY-NNNN (ej. CVE-2024-1234)"
)
# Contexto por defecto
if not context:
context = "sistema genérico"
try:
# Obtener cliente
client = get_client()
# Obtener datos del CVE
logger.info(f"Fetching CVE data for {cve_id}")
cve_data = await client.get_vulnerability(cve_id)
# Obtener datos EPSS (puede no estar disponible)
logger.info(f"Fetching EPSS data for {cve_id}")
epss_data = await client.get_epss(cve_id)
if epss_data:
logger.info(f"EPSS data found for {cve_id}")
else:
logger.info(f"No EPSS data available for {cve_id}")
# Formatear análisis de riesgo
formatted_result = format_risk_summary(cve_data, epss_data, context)
logger.info(f"Successfully generated risk summary for {cve_id}")
return formatted_result
except ValueError as e:
logger.warning(f"Validation error for {cve_id}: {e}")
raise
except Exception as e:
logger.error(f"Error generating risk summary for {cve_id}: {e}")
raise Exception(f"Error al analizar riesgo de {cve_id}: {str(e)}")