Express.js
Security headers y Helmet
Explica cómo configurar headers de seguridad con Helmet, CSP, HSTS, frame protections y políticas compatibles con proxies y recursos de la aplicación.
- Última actualización
- Actualizada
- Nivel
- Aplicación
Express.js
Explica cómo configurar headers de seguridad con Helmet, CSP, HSTS, frame protections y políticas compatibles con proxies y recursos de la aplicación.
Security headers indican al navegador qué comportamientos permitir. Helmet ayuda a configurarlos, pero cada política debe corresponder al contenido y despliegue reales.
El navegador posee capacidades que una aplicación puede restringir mediante headers: ejecución de scripts, embedding, MIME sniffing, envío de referrer, acceso a APIs y uso obligatorio de HTTPS.
Estos headers son defensa en profundidad. No corrigen autorización, validación, XSS almacenado ni una dependencia vulnerable por sí solos.
import helmet from 'helmet';
app.use(helmet());Helmet aplica defaults razonables que cambian entre versiones. Revisa los headers producidos, no instales el paquete como una caja negra.
CSP limita fuentes de contenido:
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
objectSrc: ["'none'"],
frameAncestors: ["'none'"],
upgradeInsecureRequests: [],
},
}));Para scripts inline, utiliza nonces o hashes. Un nonce debe ser impredecible y distinto por response:
script-src 'self' 'nonce-random-value'CSP puede desplegarse primero en Content-Security-Policy-Report-Only para observar violaciones sin bloquear.
Strict-Transport-Security: max-age=31536000; includeSubDomainsIndica al navegador usar HTTPS en futuras visitas. Solo se respeta cuando llega por HTTPS. includeSubDomains y preload tienen consecuencias difíciles de revertir; verifica que todos los subdominios soporten TLS.
X-Content-Type-Options: nosniffEvita que el navegador interprete una respuesta como otro tipo distinto del declarado. Esto vuelve aún más importante enviar Content-Type correcto.
CSP frame-ancestors controla quién puede embeber la página. X-Frame-Options es una defensa heredada útil para compatibilidad.
Una API JSON quizá no necesite framing, pero una app Express que sirve UI sí.
Referrer-Policy: strict-origin-when-cross-originReduce información de URLs enviada a otros sitios. No coloques secretos en URLs aunque exista esta policy.
Restringe capacidades como cámara, micrófono o geolocalización. Solo configura funciones relevantes para el frontend servido.
Estas políticas controlan aislamiento entre documentos y recursos. Pueden habilitar características como cross-origin isolation, pero rompen embeds y recursos terceros si se aplican sin análisis.
Una API y panel administrativo servidos por Express pueden usar políticas distintas:
app.use('/api', helmet({
contentSecurityPolicy: false,
}));
app.use('/admin', helmet({
contentSecurityPolicy: {
directives: adminCsp,
},
}));Desactivar CSP en endpoints JSON puede ser razonable porque no renderizan documentos, pero la UI necesita una política real. No copies esta separación sin revisar el producto.
Si TLS termina en un proxy, configura trust proxy correctamente para:
HSTS debe emitirse solo cuando el dominio realmente funciona por HTTPS. La app no debe confiar en X-Forwarded-Proto de cualquier cliente.
CSP reports pueden generar alto volumen y contener URLs sensibles. Limita, procesa y redacta. Reporting no sustituye alertas ni pruebas.
Analytics, fonts o pagos pueden requerir CSP adicional. Prefiere una allowlist mínima; evita *.
upgrade-insecure-requests puede transformar URLs y complicar localhost (se abre en otra pestaña). Configura por entorno.
Un nonce estático pierde valor porque el atacante puede conocerlo.
Una mala configuración puede dejar el dominio inaccesible por largo tiempo.
nosniff puede bloquear respuestas con Content-Type incorrecto, revelando errores que antes pasaban inadvertidos.
'unsafe-inline' sin comprender el impacto.Policies estrictas reducen superficie, pero aumentan configuración y pueden romper terceros. Comienza desde mínimo necesario y mide violaciones. La comodidad de scripts inline no debe dominar el diseño.
nosniff exige media types correctos.includeSubDomains en HSTS?Rate limiting y protección frente a abuso controla frecuencia y coste por actor, tenant o recurso.