剣 KENSAI
Caso de Estudio

De Grado B a Grado A:
Cómo Corregimos el Cumplimiento de NIS2 en 30 Minutos

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.

📅 16 de marzo de 2026 ⏱ 6 min de lectura 🏷 NIS2 · Cumplimiento · Caso de Estudio · Caddy

La Verdad Incómoda

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.


Los Resultados del Escaneo

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
A
0,997 / 1,000
Puntuación NIS2
brnz.ai
B
0,786 / 1,000
Puntuación NIS2
codeforceai.com
B
0,786 / 1,000
Puntuación NIS2

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.


Qué Faltaba — y Por Qué Importa para NIS2

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
Implicación de NIS2: Según el Artículo 21(2), las entidades reguladas deben implementar «medidas técnicas y organizativas apropiadas y proporcionadas». La falta de HSTS significa que son posibles las conexiones sin cifrar. La falta de CSP significa que los ataques XSS pueden exfiltrar datos. Las autoridades nacionales competentes tratan esto como evidencia de una seguridad básica inadecuada.
Qué exigen el Art. 21 y el Art. 25: El Art. 21 obliga a adoptar medidas de gestión de riesgos, incluidas políticas sobre seguridad de red y control de acceso. El Art. 25 introduce la «seguridad por diseño», lo que significa que los controles de seguridad deben implementarse de forma proactiva, no reactiva. La falta de cabeceras de seguridad HTTP incumple ambos requisitos.

La Solución: Configuración de Cabeceras de Caddy

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

La Cronología: 30 Minutos de Principio a Fin

T+0:00
Se inició el escaneo de KENSAI en los tres dominios
Evaluación automatizada de cumplimiento de NIS2 en cola y en ejecución.
T+0:04
Llegan los resultados del escaneo: dos dominios marcados como Grado B
brnz.ai y codeforceai.com obtuvieron 0,786 cada uno. Se identificaron seis cabeceras ausentes por dominio.
T+0:07
Análisis de la causa raíz
kensai.app ya tenía el bloque de cabeceras. A brnz.ai y codeforceai.com les faltaba por completo.
T+0:15
Configuración de Caddy actualizada
Se añadió el fragmento (security_headers) y se importó en ambos bloques de sitio. Confirmado en git.
T+0:17
Caddy recargado — cero tiempo de inactividad
caddy reload aplicó las nuevas cabeceras al instante. No se requirió reinicio.
T+0:22
Verificación mediante curl
Se confirmó la presencia de las seis cabeceras en la respuesta HTTP. No se observaron regresiones.
T+0:29
Re-escaneo completado — Grado A confirmado
Ambos dominios obtienen ahora 0,997. Cumplimiento de NIS2 restaurado. Post-mortem documentado.

Antes frente a Después

⚠ Antes
B
Puntuación: 0,786 / 1,000
  • HSTS ausente
  • CSP ausente
  • X-Frame-Options ausente
  • X-Content-Type-Options ausente
  • Referrer-Policy ausente
  • Permissions-Policy ausente
✓ Después
A
Puntuación: 0,997 / 1,000
  • HSTS con preload
  • CSP bloqueando inyecciones
  • X-Frame-Options: DENY
  • X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin
  • Permissions-Policy: bloqueado
Resultado: Tanto brnz.ai como codeforceai.com pasaron de Grado B (0,786) a Grado A (0,997) en menos de 30 minutos. El único cambio: seis cabeceras HTTP añadidas mediante la configuración de Caddy. Sin cambios de código, sin despliegues, sin tiempo de inactividad.

Lecciones Clave

1. Las cabeceras de seguridad son elementos de cumplimiento de NIS2, no extras opcionales

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

2. Incluso las empresas de seguridad tienen carencias

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.

3. La solución casi siempre es simple

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.

4. Los fragmentos reutilizables previenen la deriva futura

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.


Qué significa esto para su organización

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.

Compruebe su Cumplimiento de NIS2 — Gratis

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 →

Artículos relacionados

Informe de Seguridad del 2 de Marzo: Las Bandas de Ransomware Atacan Actualización de Regulaciones de Seguridad de Marzo de 2026: NIS2 Directiva de Emergencia de CISA sobre Cisco SD-WAN