Escaneamos nuestros propios sitios web con KENSAI y encontramos carencias críticas de cumplimiento de NIS2. La falta de cabeceras de seguridad HTTP dejó dos de nuestros tres dominios en Grado B (0,786). Esto es exactamente lo que estaba mal, qué artículos de NIS2 estaban en riesgo y cómo 30 minutos de configuración de Caddy lo arreglaron todo.
Construimos una plataforma de escaneo de seguridad. Predicamos el cumplimiento de NIS2 a nuestros clientes. Y luego ejecutamos KENSAI en nuestros propios dominios, y descubrimos que dos de cada tres no eran conformes.
Sin vulnerabilidades, sin brechas. Solo cabeceras de seguridad HTTP ausentes: el tipo de carencia silenciosa que los reguladores comprueban primero y los atacantes explotan después. Según la Directiva NIS2 (Art. 21, §2), estas cabeceras no son opcionales para las entidades reguladas. Son un requisito básico de higiene.
Esto es lo que encontramos, y con qué rapidez lo corregimos.
Ejecutamos el escaneo automatizado de cumplimiento de NIS2 de KENSAI en los tres dominios de la cartera el 15 de marzo de 2026:
kensai.app obtuvo una puntuación casi perfecta de 0,997 porque ya ejecutaba la configuración de cabeceras de Caddy correcta. Los otros dos dominios — brnz.ai y codeforceai.com — estaban ambos en 0,786, y a cada uno le faltaban las mismas seis cabeceras de seguridad críticas.
Seis cabeceras de respuesta HTTP estaban ausentes en ambos dominios no conformes. Cada una se corresponde directamente con los requisitos de la Directiva NIS2:
| Cabecera Ausente | Propósito | Referencia NIS2 | Estado |
|---|---|---|---|
Strict-Transport-Security |
Fuerza HTTPS, previene ataques de degradación de protocolo | Art. 21(2)(h) — Comunicaciones seguras | ✗ AUSENTE |
Content-Security-Policy |
Bloquea XSS, inyección de código, exfiltración de datos | Art. 21(2)(d) — Seguridad de la cadena de suministro | ✗ AUSENTE |
X-Frame-Options |
Previene el clickjacking / ataques de redirección de UI | Art. 21(2)(b) — Prevención de incidentes | ✗ AUSENTE |
X-Content-Type-Options |
Detiene los ataques de MIME-sniffing | Art. 21(2)(b) — Higiene cibernética básica | ✗ AUSENTE |
Referrer-Policy |
Controla la fuga de datos de referencia a terceros | Art. 21(2)(e) — Políticas de seguridad de datos | ✗ AUSENTE |
Permissions-Policy |
Restringe el acceso a las API del navegador (cámara, micrófono, geolocalización) | Art. 25 — Seguridad por diseño | ✗ AUSENTE |
Usamos Caddy como nuestro proxy inverso. La solución fue un único bloque header reutilizable que pudimos aplicar a todos los dominios. Esto es exactamente lo que añadimos:
# Fragmento global de cabeceras — añadir a todos los sitios de producción
(security_headers) {
header {
# Fuerza HTTPS — NIS2 Art. 21(2)(h): comunicaciones seguras
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# Bloquea XSS e inyección — NIS2 Art. 21(2)(d): seguridad de la cadena de suministro
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://fonts.googleapis.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'none'"
# Previene el clickjacking — NIS2 Art. 21(2)(b)
X-Frame-Options "DENY"
# Detiene el MIME-sniffing — NIS2 Art. 21(2)(b)
X-Content-Type-Options "nosniff"
# Limita la fuga de referrer — NIS2 Art. 21(2)(e)
Referrer-Policy "strict-origin-when-cross-origin"
# Restringe las API del navegador — NIS2 Art. 25: seguridad por diseño
Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()"
# Elimina el fingerprinting del servidor
-Server
-X-Powered-By
}
Luego importamos el fragmento en cada bloque de sitio:
# brnz.ai
brnz.ai, www.brnz.ai {
import security_headers
reverse_proxy localhost:3001
}
# codeforceai.com
codeforceai.com, www.codeforceai.com {
import security_headers
reverse_proxy localhost:3002
}
Recargue Caddy, verifique las cabeceras en las DevTools del navegador, listo:
caddy reload --config /etc/caddy/Caddyfile
Se espera que toda entidad regulada por NIS2 tenga implementadas las cabeceras de seguridad HTTP básicas. Los reguladores ejecutan cada vez más escaneos automatizados durante las auditorías. Una cabecera Strict-Transport-Security ausente no es una omisión menor: es evidencia de una gestión de riesgos inadecuada según el Art. 21(2).
Construimos herramientas de cumplimiento y aun así teníamos dos sitios en Grado B. Esto no es vergonzoso: es un recordatorio de que la deriva de configuración ocurre. Un dominio lanzado con rapidez, un Caddyfile que no se sincronizó, un import ausente. El escaneo automatizado detecta lo que las auditorías manuales pasan por alto.
Seis cabeceras ausentes. Treinta líneas de configuración de Caddy. Treinta minutos de trabajo. La distancia entre el Grado B y el Grado A no es un proyecto de un mes: es una tarde. La parte difícil es saber que la carencia existe en primer lugar.
Al extraer las cabeceras a un fragmento (security_headers) , cualquier nuevo dominio que añadamos obtiene automáticamente la cobertura completa de cabeceras de NIS2 incluyendo una única línea import . El cumplimiento se convierte en el valor por defecto, no en una ocurrencia tardía.
Si está sujeto a NIS2 —o preparándose para una auditoría—, sus cabeceras de seguridad HTTP son una de las primeras cosas que los reguladores comprueban. Son rápidas de escanear, inequívocas de evaluar y triviales de corregir. No hay excusa para un Grado B cuando un Grado A lleva 30 minutos.
Ejecute el escaneo. Lea el informe. Corrija lo señalado. Vuelva a escanear para confirmar.
Ejecute el mismo escaneo que ejecutamos en nuestros propios dominios. Obtenga su calificación de cumplimiento de NIS2, vea exactamente qué cabeceras faltan y obtenga un informe de remediación sobre el que pueda actuar de inmediato.
Iniciar Escaneo Gratuito de NIS2 →🛡️ ¿Es seguro su sitio web?
Descubra vulnerabilidades antes que los atacantes.
Analice su sitio web gratis →