HSTS (HTTP Strict Transport Security): guía completa y práctica

Autor: Jeffry Chaves, Ing. en Sistemas – Diccionario Informático

¿Qué es HSTS y por qué importa en 2025?

HSTS (HTTP Strict Transport Security) es una política que le dice al navegador: “a este dominio siempre entras por HTTPS”. Esa simple orden corta de raíz varios vectores: SSL stripping, downgrades a HTTP, enlaces antiguos sin esquema y ciertos intentos de man-in-the-middle que dependen de la negociación inicial en claro. La magia ocurre con una cabecera HTTP: Strict-Transport-Security.

Mi enfoque al explicarlo es directo: sin HSTS, confías en redirecciones 301/308 que el navegador puede pedir por HTTP la primera vez; con HSTS, el navegador recuerda la regla y ni siquiera intenta HTTP en visitas posteriores (y si estás en la lista de preload, ni en la primera). En 2025, con navegadores endurecidos y todo el mundo en TLS 1.2/1.3, HSTS es parte del “mínimo decente” en producción junto con: redirecciones canónicas a 443, Secure en cookies, SameSite, Content-Security-Policy, Referrer-Policy y X-Content-Type-Options.

Qué resuelve y qué no

  • ✅ Evita peticiones por HTTP al dominio (y subdominios si lo indicas).

  • ✅ Reduce superficie de ataque en redes inseguras (cafeterías, aeropuertos).

  • ❌ No corrige certificados inválidos ni mixed content.

  • ❌ No sustituye CSP ni protege contra XSS/CSRF.

Inserta aquí tu experiencia (1): “Cuando migré mi sitio corporativo, activé HSTS tras limpiar mixed content para evitar errores masivos.”


Cómo funciona HSTS: directivas y flujo del navegador

HSTS funciona porque el navegador memoriza la política durante max-age segundos y aplica reglas estrictas:

Directivas clave (H3)

  • max-age=<segundos>: tiempo que el navegador aplica la política. Recomendación habitual en producción: 31536000 (1 año).

  • includeSubDomains: extiende la política a todos los subdominios. Úsala solo cuando tengas inventariados y en HTTPS todos tus subdominios.

  • preload: pides ser incluido en la lista de precarga de los navegadores. Requisitos: max-age >= 31536000, includeSubDomains y cabecera en el dominio raíz.

Ciclo típico

  1. Primera visita por HTTPS: el servidor envía Strict-Transport-Security.

  2. El navegador guarda la política el tiempo indicado.

  3. Cualquier intento futuro a http://tu-dominio se “reescribe” a https://tu-dominio antes de salir del navegador.

  4. Con preload, el paso 1 se omite: el navegador ya conoce la regla desde su lista interna.

Inserta aquí tu experiencia (2): “En mi SaaS activé includeSubDomains solo tras mover api. y cdn. a TLS; antes, lo dejé sin esa directiva para no romper servicios.”


Requisitos previos y checklist antes de activarlo

Antes de tocar nada, me aseguro de esto:

Checklist esencial

  • Certificado TLS válido (dominio y cadenas correctas, sin SHA-1, sin caducidad próxima).

  • Redirecciones: HTTP→HTTPS con 301/308; una sola cadena, sin bucles.

  • Inventario de subdominios (DNS): ¿todos sirven por HTTPS? ¿Alguno es legacy (intranet, impresoras, cámaras)?

  • Contenido mixto eliminado (scripts, imágenes, iframes por HTTP).

  • Cookies sensibles con Secure y SameSite=Lax/Strict.

  • Monitorización lista (logs, alertas) y plan de rollback.

  • Entorno de staging representativo para probar la cabecera.

Valores iniciales seguros

  • Fase 1 (observación): max-age=300 (5 min) sin includeSubDomains.

  • Fase 2 (confianza): max-age=86400 (1 día).

  • Fase 3 (estable): max-age=31536000; includeSubDomains.

  • Fase 4 (opcional): añadir preload cuando estés 100% seguro.


Implementación por servidor (Apache, Nginx, IIS, proxies/CDN)

Apache (H3)

Habilita mod_headers y añade en el vhost HTTPS:

# /etc/apache2/sites-available/tu-sitio.conf
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>

Reinicia o recarga:

sudo a2enmod headers
sudo systemctl reload apache2

Nginx (H3)

Colócalo únicamente en server blocks de 443:

server {
listen 443 ssl http2;
server_name tu-dominio.com;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# resto de configuración...
}

Evita enviarlo por 80 para no romper flujos de desactivación y mantenerlo solo bajo TLS.

Inserta aquí tu experiencia (3): “En Nginx me encontré que sin always no se devolvía en algunos 301/4xx; con always, quedó estable.”

IIS / Windows (H3)

En web.config del sitio HTTPS:

<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

Cloudflare (H3)

  • SSL/TLS → HSTS: actívalo en el panel (elige max-age, includeSubDomains, preload).

  • Si usas transform rules, asegúrate de no sobrescribir la cabecera.

Traefik / Kubernetes Ingress (H3)

Traefik (static/dynamic config):

http:
middlewares:
hsts:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: false

K8s NGINX Ingress:

metadata:
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Precarga (preload): cuándo usarla y cómo enviarla

Cuándo sí: cuando todos tus subdominios actuales y futuros deben forzar HTTPS. Portales, APIs, paneles admin, estáticos: todo bajo TLS.
Cuándo no: ecosistemas con subdominios temporales, laboratorios, dispositivos, o integraciones de terceros que no controlas.

Requisitos habituales para aplicar a la lista de preload

  • Strict-Transport-Security: max-age=31536000; includeSubDomains; preload en el dominio raíz.

  • Redirección HTTP→HTTPS activa en raíz y subdominios.

  • Certificado universal válido y renovaciones automatizadas.

Proceso resumido

  1. Activa la cabecera con preload en producción.

  2. Verifica que todo responde bien.

  3. Solicita inclusión en la lista de preload correspondiente (Chrome “HSTS preload list”, que heredan otros navegadores).

  4. Monitorea y entiende que revertir puede tardar (dependes de ciclos de actualización de navegadores).

Inserta aquí tu experiencia (4): “Añadí preload solo después de 30 días sin incidencias en todos los subdominios.”


Errores comunes y cómo arreglarlos (mixed content, subdominios, cachés)

  • Contenido mixto: recursos por HTTP rompen la carga bajo políticas estrictas. Solución: búsqueda y reemplazo de esquemas, usar // solo si todo va por HTTPS, preferir rutas relativas.

  • Subdominios olvidados: old.admin.tu-dominio.com sin TLS + includeSubDomains = incidencia. Mantén inventario DNS y pruebas automatizadas.

  • Enviar HSTS por HTTP: inútil (el navegador no confía); envíalo solo por HTTPS.

  • max-age desmesurado al inicio: empieza corto; escala con confianza.

  • Cachés/CDN: revisa que no “desaparezcan” cabeceras en 301/4xx/5xx.

  • IPs y puertos no estándar: HSTS es por host/puerto 443; no “arregla” servicios en 8443/puertos custom si el navegador no aplica la política allí.


Pruebas, verificación y rollback seguro

Pruebas rápidas

# Ver la cabecera desde el origen/CDN
curl -I https://tu-dominio.com | grep -i strict-transport-security

# Simular redirecciones y ver si se mantiene
curl -IL http://tu-dominio.com

DevTools: pestaña Network, selecciona la respuesta y mira Response Headers.
Scanners: Security Headers, SSL Labs para el estado TLS.

Automatiza en CI/CD

  • Job que falla el deploy si falta la cabecera en rutas críticas.

  • Test de inventario: recorrer subdominios conocidos y validar HTTPS + HSTS.

Rollback seguro

  • Para desactivar: enviar por HTTPS Strict-Transport-Security: max-age=0.

  • Mantén la cabecera con max-age=0 el tiempo suficiente para que clientes actualicen su estado.

  • Si estabas en preload, solicita removal; el efecto tarda (planifica).


Buenas prácticas, seguridad y privacidad (limitaciones reales)

  • HSTS no evita todo MITM: si el atacante posee un certificado válido (compromiso CA, phishing con dominio parecido), la política no detecta eso.

  • Primera visita: sin preload, la primera visita podría ser por HTTP si el usuario teclea sin esquema; por eso siempre redirecciona 80→443 y promueve enlaces HTTPS.

  • Privacidad: la pertenencia a la lista de preload podría usarse como bit de rastreo muy limitado entre sitios, pero el riesgo práctico es bajo frente a los beneficios de seguridad.

  • Lleva registro de renovaciones TLS y usa OCSP stapling/ACME para evitar sorpresas.


SEO técnico y rendimiento en migraciones a HTTPS

  • SEO: HSTS no es un factor directo, pero refuerza la consistencia en HTTPS y previene duplicidad HTTP/HTTPS. Asegura canónicas a HTTPS, actualiza sitemaps, y evita cadenas largas de redirección.

  • Rendimiento: al evitar el salto HTTP→HTTPS en clientes recurrentes, reduces un RTT (pequeña mejora de TTFB percibido).

  • Señales: mezcla HSTS con upgrade-insecure-requests en CSP para acelerar limpieza de mixed content (con cuidado).


Preguntas frecuentes sobre HSTS

¿Cuál es un max-age recomendado?
Empiezo con minutos/horas en pruebas; en producción estable, 1 año (31536000).

¿Debo activar includeSubDomains?
Sí, si todos tus subdominios están en HTTPS y controlados. Si dudas, deja margen y ve migrando por fases.

¿Cuándo usar preload?
Cuando tu arquitectura esté totalmente en TLS y tengas procesos que garanticen que nuevos subdominios también lo estarán.

¿Cómo sé si mi cabecera sale en todos los códigos (200/301/4xx)?
Usa add_header ... always (Nginx) o reglas equivalentes para no perderla en redirecciones/errores.

¿Cómo desactivo HSTS si rompí algo?
Envía max-age=0 por HTTPS en el dominio afectado, corrige el problema y luego vuelve a activar con una ventana corta.


Conclusión

HSTS es un must en cualquier sitio serio en 2025. Mi receta: limpia mixed content, asegura redirecciones y cookies, empieza con max-age corto, monitoriza y escala hasta el año con includeSubDomains. Cuando tu ecosistema esté maduro, valora preload. Documenta un rollback y automatiza pruebas: así duermes tranquilo y reduces sorpresas.

2 respuestas

  1. Este artículo es una lección divertida sobre cómo forzar a los usuarios a usar HTTPS como si fueran los capos de una banda sin concesiones (HSTS). El checklist previo me recuerda la preparación que se necesita antes de lanzar la orden: certificados, redirecciones perfectas y un inventario de subdominios que a veces parecen un laberinto de ¿tú qué sabes, api.cdn.subdominio legacy?. La fase 4 de preload es como el estampillado oficial de ¡Estás en la banda!, ¡con todo el peso de los navegadores! Los errores comunes son los clásicos de las bandas, como el contenido mixto que canta en la otra estación de radio (HTTP). En fin, un manual del malibundo para asegurar que todo funcione bajo la sombra de HTTPS, ¡con un toque de no me movas, que soy del nuevo equipo!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *