HSTS (HTTP Strict Transport Security) es una cabecera de seguridad que indica a los navegadores que siempre se conecten vía HTTPS — incluso si el usuario escribe http:// o hace clic en un enlace HTTP. Una vez que un navegador recibe una cabecera HSTS, automáticamente actualiza todas las futuras solicitudes a HTTPS para ese dominio, previniendo ataques de degradación y conexiones inseguras.
Por qué HSTS importa
Sin HSTS, la primera solicitud a tu sitio puede ser HTTP (antes de que la redirección 301 actúe). Durante esa breve ventana, un atacante en la red puede:
- Eliminar HTTPS — interceptar la redirección y mantener al usuario en HTTP (ataque de SSL stripping)
- Robar cookies — si las cookies se envían en la solicitud HTTP inicial
- Inyectar contenido — modificar la respuesta de redirección
HSTS elimina esta ventana. Después de la primera visita HTTPS, el navegador nunca intenta HTTP de nuevo.
Cómo habilitar HSTS
Nginx
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
Añade esto dentro de tu bloque server HTTPS (puerto 443), no en el bloque de redirección HTTP.
Apache
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Requiere mod_headers (sudo a2enmod headers).
Cloudflare
Panel → SSL/TLS → Edge Certificates → HTTP Strict Transport Security (HSTS) → Habilitar.
Parámetros HSTS
| Parámetro | Ejemplo | Significado |
|---|---|---|
max-age | 63072000 (2 años) | Cuánto tiempo (en segundos) el navegador recuerda usar HTTPS |
includeSubDomains | — | Aplica HSTS también a todos los subdominios |
preload | — | Señala la intención de unirse a la lista de precarga HSTS |
Elegir max-age
| Fase | max-age | Propósito |
|---|---|---|
| Prueba | 300 (5 minutos) | Verificar que HTTPS funcione antes de comprometerse |
| Confianza | 604800 (1 semana) | Bajo riesgo si necesitas revertir |
| Producción | 31536000 (1 año) | Recomendación estándar |
| Largo plazo | 63072000 (2 años) | Requerido para la lista de precarga |
Empieza con valores pequeños, aumenta gradualmente. Si HTTPS se rompe mientras un max-age largo está en caché, los visitantes no pueden acceder a tu sitio en absoluto — el navegador se niega a conectar por HTTP.
Precarga HSTS
La lista de precarga HSTS es una lista de dominios codificados en los navegadores para siempre usar HTTPS, incluso en la primera visita (antes de recibir cualquier cabecera HSTS).
Requisitos para la precarga
- Servir un certificado HTTPS válido
- Redirigir HTTP a HTTPS en el mismo host
- Cabecera HSTS con
max-age>= 63072000 (2 años) - Incluir la directiva
includeSubDomains - Incluir la directiva
preload
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
Enviar para precarga
Ve a hstspreload.org, ingresa tu dominio y envía. Después de la revisión (semanas a meses), tu dominio se añade a las listas integradas de los navegadores.
Advertencias sobre la precarga
- Es difícil de deshacer. La eliminación de la lista de precarga tarda meses y requiere un ciclo de lanzamiento del navegador. Durante ese tiempo, tu dominio solo puede accederse por HTTPS.
includeSubDomainses obligatorio — cada subdominio debe soportar HTTPS. Sistaging.example.comno tiene certificado, se vuelve inaccesible.- Solo precarga si estás seguro de que todos los subdominios actuales y futuros soportarán HTTPS.
Errores comunes
Configurar HSTS en la respuesta HTTP
HSTS debe enviarse solo por HTTPS. Si tu redirección HTTP también envía la cabecera HSTS, los navegadores la ignoran (la especificación requiere HTTPS). Configura la cabecera solo en tu bloque del puerto 443.
Olvidar los subdominios
includeSubDomains aplica HSTS a todos los subdominios. Si internal.example.com no tiene HTTPS, se vuelve inalcanzable. Audita todos los subdominios antes de habilitar.
Configurar max-age demasiado alto demasiado pronto
Si HTTPS se rompe (certificado expirado, error de configuración), los visitantes no pueden volver a HTTP. Su navegador se niega a conectar. Empieza con 5 minutos, verifica que todo funcione, luego aumenta a 1 año.
Cómo verificar si HSTS está activo
curl -sI https://yourdomain.com | grep -i strict-transport
# Expected: strict-transport-security: max-age=63072000; includeSubDomains
En Chrome DevTools: pestaña Network → haz clic en la solicitud → Headers → busca Strict-Transport-Security.
Preguntas frecuentes
¿HSTS reemplaza las redirecciones HTTP→HTTPS?
No. HSTS y las redirecciones sirven para propósitos diferentes. La redirección captura la primera solicitud HTTP. HSTS le dice al navegador que nunca haga solicitudes HTTP de nuevo (después de la primera visita HTTPS). Necesitas ambos.
¿HSTS puede causar problemas?
Sí, si HTTPS se rompe. Con un max-age largo, los navegadores se niegan a conectar por HTTP como alternativa. Por esto deberías empezar con un max-age corto y solo aumentar una vez que HTTPS sea estable.
¿Necesito HSTS si estoy en Cloudflare?
Cloudflare maneja la conexión visitante→Cloudflare, pero HSTS en tu origen protege la cadena completa. Habilita HSTS a través del panel de Cloudflare para el borde, y en tu origen si usas modo Full (Strict).
¿Cuál es la diferencia entre HSTS y la directiva CSP upgrade-insecure-requests?
upgrade-insecure-requests le dice al navegador que cargue sub-recursos (imágenes, scripts) por HTTPS en lugar de HTTP — solucionando contenido mixto. HSTS le dice al navegador que siempre use HTTPS para todo el dominio. Resuelven problemas diferentes y pueden usarse juntos.