Qué hace
Escribes un ID de CVE, como CVE-2021-44228 (Log4Shell), y obtienes una página con siete capítulos, siempre en el mismo orden:
- El ID del CVE, su título y cuándo se publicó.
- Gravedad: la puntuación CVSS con una insignia de color y el nivel escrito con una palabra.
- Si se está explotando: la lista de vulnerabilidades explotadas conocidas de CISA (KEV) y la probabilidad EPSS.
- Un resumen en lenguaje claro.
- Qué productos y versiones están afectados.
- La corrección y la mitigación: lo que exige CISA, las primeras versiones no afectadas, parches y avisos.
- Referencias.
Hay dos vistas de los mismos datos. La vista Manager responde a «¿tenemos que actuar hoy?». La vista Analyst conserva el detalle. Cada resumen termina con «Always verify with the official vendor advisory» (verifica siempre con el aviso oficial del fabricante).
Cómo funciona
Es una página estática y una función sin servidor, sin cuentas, sin base de datos y sin dependencias. Con cada petición, la función ejecuta estos pasos en orden:
- Comprobar el método y limitar la tasa de peticiones del cliente.
- Validar el ID. Debe cumplir
^CVE-\d{4}-\d{4,10}$y ser el único parámetro de la consulta. - Mirar la caché. Si ya hay otra petición en curso para el mismo ID, esperar a esa en lugar de volver a preguntar.
- Consultar NVD, el feed KEV de CISA y EPSS en paralelo, cada uno con su propio tiempo límite.
- Normalizar los datos no confiables en una forma pequeña y fija.
- Escribir el resumen: con un modelo de IA si hay una clave configurada, y con reglas fijas si no.
NVD es obligatorio. Si CISA, EPSS o el modelo de IA fallan, la página sigue funcionando e indica qué falta. «No se pudo comprobar la lista de CISA» se muestra como desconocido, nunca como «no explotado», porque una consulta fallida que parece una buena noticia es lo peor que puede hacer una herramienta de seguridad. Por la misma razón, un feed KEV con menos de 100 entradas se considera roto.
Las decisiones de seguridad
Los datos vienen de bases de datos públicas, pero cualquiera puede influir en parte de ellos, y un modelo de IA los lee. Por eso todo se trata como hostil.
| Amenaza | Qué hice |
|---|---|
| Filtración de claves de API | Las claves se leen de variables de entorno en un solo archivo del servidor. El código del navegador nunca las menciona, y una prueba revisa todos los archivos del repositorio en busca de cadenas con forma de clave. |
| Entradas malas y SSRF | Un patrón de ID estricto y solo ASCII. Los tres hosts de las API son constantes, el ID entra mediante URL.searchParams y se rechazan las redirecciones. |
| XSS | El servidor limpia el texto y limita las longitudes. El navegador escribe solo con textContent. Una Content Security Policy estricta con Trusted Types es la última barrera. |
| Inyección de prompts | El modelo recibe solo hechos públicos, sin herramientas ni secretos. Su respuesta debe ser un objeto JSON de tres campos, y se rechaza si contiene un enlace, una etiqueta o un número de versión que no esté en los hechos. |
| Abuso y cuota | 20 peticiones por minuto por cliente, 6 consultas sin caché por minuto, un presupuesto compartido justo por debajo del límite de NVD y una hora de caché. |
| Datos hostiles de origen | Se comprueba el tipo de cada campo, se limitan los bucles y los tamaños, y se rechaza un registro sobre un CVE distinto del solicitado. |
Hay más de 140 pruebas sobre respuestas reales de las API guardadas, así que se ejecutan sin conexión. La más útil es un simulacro de XSS que ejecuta el código real del navegador contra una respuesta llena de cargas <img onerror> y <script>, y falla ante cualquier elemento, atributo o enlace inesperado.
Lo que todavía no puede hacer
- La caché y el limitador de tasa viven en la memoria de una instancia de la función, así que funcionan «en la medida de lo posible». Un almacén compartido lo arreglaría.
- La cuota de NVD la comparten todos los visitantes. Si se agota, la página muestra un mensaje de «ocupado».
- Un modelo de IA persuadido aún puede escribir una frase engañosa que no contenga ningún enlace ni número de versión. Las comprobaciones no pueden detectar una opinión, y por eso la gravedad, KEV y EPSS se muestran aparte del resumen.
- KEV solo recoge explotación confirmada, y EPSS es una probabilidad, no un veredicto.
- Probé un navegador Chromium, en ambos temas, en anchos de escritorio y de móvil. No probé Safari ni Firefox.
Lo construí con ayuda de IA. Diseñé las funciones y los requisitos de seguridad, y revisé y probé el código.
Pruébalo
El verificador está en explain-this-cve.vercel.app, y el código y una guía de estudio están en GitHub. Prueba primero con Log4Shell.