CTI Dashboard — Cyber Threat Intelligence
BASE4 Security R&D+i
Dashboard de inteligencia de amenazas cibernéticas que se actualiza diariamente de forma autónoma, ingiere datos de múltiples fuentes públicas y modela las relaciones entre actores, vulnerabilidades, ataques y targets como un grafo interactivo.
┌─────────────────────────────────────────────────────────────────┐
│ INGESTION LAYER │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ NVD API │ │ CISA KEV │ │ MITRE │ │ Claude + WebSearch│ │
│ │ (CVEs) │ │ (Exploits)│ │ ATT&CK │ │ (Noticias/Context)│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────────┬─────────┘ │
│ └─────────────┴────────────┴────────────────┘ │
│ │ │
│ ┌─────▼──────┐ │
│ │ Normalizer │ (Schema unificado) │
│ └─────┬──────┘ │
│ │ │
├──────────────────────────▼──────────────────────────────────────┤
│ DATA LAYER │
│ ┌──────────────┐ ┌────────────────┐ │
│ │ SQLite │ │ Graph Index │ │
│ │ (sql.js WASM)│ │ (adjacency + │ │
│ │ CVEs, actors │ │ metadata) │ │
│ │ events │ │ │ │
│ └──────┬───────┘ └───────┬────────┘ │
│ └──────────────────┘ │
│ │ │
├──────────────────────────▼──────────────────────────────────────┤
│ API LAYER (Hono REST) │
│ GET /api/cves GET /api/actors │
│ GET /api/graph GET /api/timeline │
│ GET /api/campaigns GET /api/geo │
│ GET /api/stats POST /api/update │
│ GET /api/search?q= POST /api/import │
│ GET /api/export/:fmt GET /api/health │
│ │
├──────────────────────────▼──────────────────────────────────────┤
│ FRONTEND (React + D3.js) │
│ ┌────────┐ ┌───────┐ ┌──────┐ ┌────────┐ ┌────────┐ │
│ │GeoMap │ │ForceG │ │CVE │ │Timeline│ │Campaign│ │
│ │(world) │ │(graph)│ │Explor│ │ │ │View │ │
│ └────────┘ └───────┘ └──────┘ └────────┘ └────────┘ │
│ │
├──────────────────────────▼──────────────────────────────────────┤
│ AUTOMATION LAYER │
│ ┌────────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ Cron (daily) │ │ Health Check│ │ CISA KEV │ │
│ │ 06:00 UTC │ │ /api/health │ │ Enrichment │ │
│ └────────────────┘ └─────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Capa
Tecnología
Runtime
Node.js 20+ con TypeScript (ESM)
Backend
Hono (lightweight HTTP framework)
Database
SQLite via sql.js (WASM, zero-config, portable)
ORM
Drizzle ORM (type-safe)
Scheduler
node-cron (job diario 06:00 UTC)
Frontend
React 19 + TypeScript + Vite
Styling
Tailwind CSS (dark/cyber terminal theme)
Grafos
D3.js v7 (force-directed layout)
Mapas
d3-geo + world-atlas (Mercator SVG, sin tiles externos)
Fonts
JetBrains Mono (code) + Orbitron (display)
AI
Anthropic API (Claude + web_search para contexto diario)
Monorepo
pnpm workspaces (shared, server, client)
Deploy
Docker multi-stage
CVES-Visualizer/
├── package.json # Workspace root
├── pnpm-workspace.yaml
├── docker-compose.yml
├── Dockerfile
├── .env.example
├── shared/ # Tipos y constantes compartidos
│ └── src/
│ ├── types.ts # CVE, ThreatActor, GraphData, etc.
│ ├── constants.ts # Colores, iconos, severidades
│ └── index.ts
├── server/ # Backend Hono + SQLite
│ └── src/
│ ├── index.ts # Entry point: HTTP + cron
│ ├── db/
│ │ ├── client.ts # sql.js init, getDb(), saveDatabase()
│ │ ├── schema.ts # Drizzle table definitions
│ │ └── seed.ts # Seed con datos reales marzo 2026
│ ├── ingestion/
│ │ ├── nvd.ts # NVD API v2 client (CVEs)
│ │ ├── cisa-kev.ts # CISA KEV catalog
│ │ ├── claude-intel.ts # Claude + web_search
│ │ ├── normalizer.ts # Unifica data de todas las fuentes
│ │ └── scheduler.ts # Cron job + pipeline
│ ├── graph/
│ │ ├── builder.ts # Construye grafo desde DB
│ │ ├── analyzer.ts # Métricas (degree, components)
│ │ └── exporter.ts # GEXF, GraphML, Graph Hunter
│ ├── routes/ # 11 route files (REST API)
│ └── utils/
│ ├── logger.ts # pino structured logging
│ ├── rate-limiter.ts # Rate limiting APIs externas
│ └── health.ts # Health check
├── client/ # Frontend React + D3
│ └── src/
│ ├── App.tsx # Layout + tabs + routing
│ ├── api/client.ts # Fetch wrapper tipado
│ ├── hooks/ # React Query hooks
│ ├── components/
│ │ ├── map/ # GeoMap SVG con Mercator + world-atlas
│ │ ├── graph/ # ForceGraph D3 + controles + leyenda
│ │ ├── cves/ # CVEExplorer + CVECard + CVEDetail modal
│ │ ├── timeline/ # Timeline vertical con severity dots
│ │ ├── campaigns/ # Campaign cards
│ │ ├── update/ # UpdatePanel + ImportPanel + History
│ │ ├── layout/ # Header, StatCards, Sidebar, Footer
│ │ └── shared/ # SeverityBadge, SearchInput, EmptyState
│ ├── lib/ # Helpers: colors, format, mercator
│ └── styles/index.css # Tailwind + CSS custom (scanlines, pulses)
└── scripts/
├── run-update.ts # Trigger update manual
├── update-status.ts # Check último update
└── export-graph.ts # Export a JSON/GEXF/GraphML/CSV
NVD (National Vulnerability Database)
URL : https://services.nvd.nist.gov/rest/json/cves/2.0
Datos : CVEs con CVSS score, CWE, description, references
Rate limit : 5 req/30s con API key, 5 req/30s sin key
Frecuencia : Cada update diario + import manual bajo demanda
CISA KEV (Known Exploited Vulnerabilities)
URL : https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json
Datos : CVEs activamente explotados in-the-wild
Uso : Enriquecimiento automático — marca exploitedInWild = true en CVEs existentes
Claude + Web Search (opcional, requiere API key)
API : Anthropic claude-sonnet-4-20250514 con tool web_search
Datos : Contexto de noticias, campañas activas, actor updates, geo events
Output : JSON estructurado con CVEs, eventos, actores, campañas, links
Node.js 20+ (testeado con Node 24)
pnpm (npm install -g pnpm)
git clone https://github.com/lsotomayob4/CVES-Visualizer.git
cd CVES-Visualizer
pnpm install
cp .env.example .env
Variables de Entorno (.env)
# Requerido para Claude intelligence (opcional para funcionar)
ANTHROPIC_API_KEY=sk-ant-...
# Opcional: mejora rate limits de NVD
NVD_API_KEY=
# Puerto del servidor (default 3001)
PORT=3001
# Path de la base de datos SQLite
DB_PATH=./data/threat-intel.db
# Nivel de log: debug, info, warn, error
LOG_LEVEL=info
# Cron expression para update diario (default: 06:00 UTC)
UPDATE_CRON=0 6 * * *
Carga datos reales de marzo 2026:
18 CVEs (11 CRITICAL, 9 exploited in the wild)
14 Threat Actors (APT28, APT34, GlassWorm, Tycoon 2FA, etc.)
12 Geo Events con coordenadas reales
5 Campañas (Operation Epic Fury, GlassWorm Supply Chain, etc.)
12 Timeline Events
57 Graph Links
pnpm dev # Backend (tsx watch :3001) + Frontend (vite :5173) concurrentes
pnpm build # Compila shared → server → client
pnpm start # Corre server compilado en :3001 (sirve frontend estático)
pnpm db:seed # Seed con datos de marzo 2026
pnpm update:run # Trigger pipeline completo (NVD + CISA + Claude)
pnpm update:status # Ver último update
pnpm export:json # Grafo completo en JSON
pnpm export:gexf # Formato Gephi (GEXF)
pnpm export:csv # Tablas CVEs + Actors en CSV
docker compose up -d # Levanta todo con volumen para SQLite
SVG con proyección Mercator y contornos de países (world-atlas 110m)
Puntos animados por severidad (pulse rings)
Líneas punteadas animadas entre eventos que comparten actores
Click en punto → sidebar con detalle completo
Grafo de Amenazas (Force-Directed)
5 tipos de nodos: ☠ Actor, ⚠ CVE, ⚡ Attack, ◎ Target, ⬡ Campaign
Tamaño de nodos CVE escalado por CVSS score
Flechas en links coloreadas por tipo de relación
Drag & drop, zoom & pan
Filtros por tipo de nodo
Click en nodo → sidebar con descripción completa, metadata, links a NVD
Búsqueda por ID, producto, vendor
Filtros: severidad (CRITICAL/HIGH/MEDIUM/LOW), rango de fechas
Sort: CVSS, fecha, severidad
Click en CVE → modal con descripción completa, CVSS gauge, status badges, links a NVD y MITRE
Paginación
Importación de CVEs Históricos
Panel de importación en tab "Update"
Filtros: rango de fechas, keyword (NVD search), vendor, CVSS mínimo, severidad, max resultados
Presets rápidos: 7 días, 30 días, 90 días, 1 año
Auto-enriquecimiento con CISA KEV (marca exploited in the wild)
Fuentes: NVD API v2 + CISA KEV
Línea vertical con gradiente de severidad
Eventos con badges de CVEs y actores relacionados
Filtro por severidad
Cards con status (ACTIVA/DISRUPTADA), severidad
Tags de actores, targets, técnicas, CVEs
Filtro activas/todas
JSON : grafo completo (nodos + links + metadata)
CSV : tabla de CVEs, tabla de actores
GEXF : formato Gephi para análisis de grafos
GraphML : para herramientas de graph analysis
Graph Hunter : formato compatible con Graph Hunter MCP
Cron job diario a las 06:00 UTC
Pipeline: NVD → CISA KEV → Claude (si hay API key) → Normalización → DB
Retry automático (max 3 intentos, 1 hora entre reintentos)
Logging estructurado con pino
Graceful degradation (si una fuente falla, las demás siguen)
Método
Ruta
Descripción
GET
/api/health
Health check (DB, uptime, counts)
GET
/api/stats
Dashboard stats agregados
GET
/api/cves
Listar CVEs (filtros: severity, search, sort, page)
GET
/api/cves/:id
CVE individual
GET
/api/cves/prioritized
CVEs por riesgo contextual (PACO integration)
GET
/api/actors
Listar threat actors
GET
/api/actors/:id
Actor individual
GET
/api/graph
Grafo completo (nodes + links)
GET
/api/geo
Geo events para el mapa
GET
/api/timeline
Timeline events
GET
/api/campaigns
Campañas
GET
/api/search?q=
Búsqueda full-text
POST
/api/update
Trigger update manual
GET
/api/update/status
Último update log
GET
/api/update/history
Historial de updates
POST
/api/import
Importar CVEs históricos con filtros
GET
/api/export/json
Export grafo JSON
GET
/api/export/gexf
Export GEXF
GET
/api/export/graphml
Export GraphML
GET
/api/export/csv/cves
Export CVEs CSV
GET
/api/export/csv/actors
Export Actors CSV
GET
/api/export/graph-hunter
Export Graph Hunter format
Campo
Tipo
Descripción
id
TEXT PK
CVE-YYYY-NNNNN
cvss
REAL
Score 0.0–10.0
severity
TEXT
CRITICAL, HIGH, MEDIUM, LOW
product
TEXT
Nombre del producto
vendor
TEXT
Nombre del vendor
description
TEXT
Descripción (español o inglés)
exploitedInWild
BOOLEAN
Si está en CISA KEV
patchAvailable
BOOLEAN
Si hay parche
datePublished
TEXT
Fecha de publicación
attackVector
TEXT
Network, Local, Physical, Adjacent
cweId
TEXT
CWE-XXX
references
JSON
Array de URLs
source
TEXT
nvd, cisa, claude, manual
Campo
Tipo
Descripción
id
TEXT PK
Ej: apt28, glassworm
label
TEXT
Nombre visible
origin
TEXT
País/región
lat, lng
REAL
Coordenadas
ttps
JSON
Array de MITRE technique IDs
active
BOOLEAN
Estado actual
Campo
Tipo
Descripción
sourceId
TEXT
Nodo origen
targetId
TEXT
Nodo destino
type
TEXT
exploits, uses, targets, includes, affects
confidence
REAL
0.0–1.0
Graph Hunter : GET /api/export/graph-hunter — grafo temporal para threat hunting
PACO : GET /api/cves/prioritized — CVEs por riesgo para SOC triage
Gephi : GET /api/export/gexf — análisis visual de grafos
Proyecto interno de BASE4 Security R&D+i.