Forzando HTTPS Real: Cómo Configurar la Cabecera HSTS

PUNTOS CLAVE

  • HSTS obliga al navegador a usar siempre HTTPS antes de contactar con el servidor.
  • Evita ataques de degradación (SSL Stripping) y secuestro de cookies.
  • Una mala configuración puede dejar tu sitio inaccesible de forma persistente.
  • Se puede implementar vía .htaccess o mediante funciones de PHP en el core.

Tener un certificado SSL activo es solo el primer paso. Muchos sitios web «seguros» siguen siendo vulnerables porque permiten una conexión inicial por HTTP antes de redirigir al protocolo seguro. Es un riesgo innecesario. Los atacantes pueden interceptar esa breve ventana de tiempo. La implementación de cabeceras HTTP de Strict-Transport-Security (HSTS) en WordPress soluciona esto de raíz, indicándole al navegador que ni siquiera intente buscar la versión no cifrada de tu web.

#Entendiendo el mecanismo de protección HSTS

HSTS es una directiva de seguridad. Una instrucción clara. Cuando el servidor envía esta cabecera, el navegador la guarda en su memoria interna. A partir de ese momento, cualquier intento de acceder a tu dominio se traducirá automáticamente a HTTPS internamente en el cliente. Parece mentira que estemos en 2026 y todavía veamos sitios corporativos que confían únicamente en una redirección 301. Las redirecciones son lentas y vulnerables a ataques de Man-in-the-Middle.

TÉRMINO RELACIONADO

SSL Stripping: Un tipo de ataque donde un hacker intercepta la petición HTTP inicial del usuario y le sirve una versión falsa no cifrada, impidiendo que la redirección a HTTPS llegue a ocurrir.

#Implementación Técnica: El método del servidor

Tras revisar profundamente la documentación de la Mozilla Observatory, queda claro que la forma más eficiente es hacerlo desde el servidor. Así, la instrucción viaja antes que cualquier proceso de WordPress. Si tu servidor corre sobre Apache, solo necesitas añadir una línea de código.

#Configurar en la raíz del sitio dentro de .htaccess:

apache
# Forzar HSTS (Strict-Transport-Security)
# max-age=31536000 indica que el navegador debe recordar esto durante un año.
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

TIP PRO

No añadas la directiva preload hasta que estés 100% seguro de que tu certificado SSL no va a caducar ni dar errores. Si entras en la lista de precarga de los navegadores, salir es un proceso burocrático tedioso.

#Filtro alternativo mediante PHP

Si no tienes acceso al archivo del servidor o prefieres manejarlo desde tu tema, puedes usar un hook de WordPress. Resulta cuestionable que la implementación estándar pase por cargarlo en cada ejecución de script, pero es una solución válida para entornos restringidos.

#Añadir al final del archivo functions.php:

php
/**
 * Inyectamos la cabecera HSTS en el header de la respuesta.
 * Solo si la conexión actual ya es HTTPS para cumplir el estándar.
 */
add_action( 'send_headers', function() {
    if ( is_ssl() && !is_admin() ) {
        // Establecemos la seguridad estricta para el dominio y subdominios
        header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' );
    }
}, 10 );

#Caso real: El bucle de redirecciones que «bloqueó» una intranet

Me pasó con un cliente hace un par de años. Tenían una intranet en un subdominio que aún usaba un desarrollo antiguo sin SSL. Al activar HSTS en el dominio principal con la opción includeSubDomains, la intranet dejó de funcionar instantáneamente. Los navegadores de los empleados se negaban a cargar la web por HTTP.

El síntoma fue un error persistente de «Conexión no segura» que no se arreglaba vaciando la caché de WordPress. Los técnicos de soporte estaban desconcertados. En un primer intento de solución desesperada, intenté desactivar la cabecera en el .htaccess, pero el problema seguía ahí. Nada cambiaba. El error era que los navegadores ya habían «memorizado» la instrucción HSTS.

Cualquier sysadmin que haya sobrevivido a un problema de SSL sabe que la memoria del navegador es persistente. Tuve que guiar a los usuarios para que limpiaran manualmente el estado HSTS en sus navegadores Chrome mediante chrome://net-internals/#hsts. Fue una lección de humildad técnica: nunca uses includeSubDomains si no tienes control absoluto sobre toda tu infraestructura.

#Protocolo de rescate: Cómo volver atrás si te quedas fuera

HSTS es potente porque es difícil de romper. Si activas esta cabecera y tu certificado SSL expira o da error, nadie podrá entrar a tu web. Ni tú mismo. No hay botón de «Ignorar riesgo y continuar». El navegador simplemente bloquea el acceso.

Si esto ocurre, entra por SFTP a tu servidor y elimina la línea del .htaccess o el código de functions.php. Para los usuarios que ya entraron, tendrás que esperar a que el max-age expire (lo cual puede tardar un año) o pedirles que limpien el historial de seguridad de su propio navegador. No es el escenario ideal, así que testea con un max-age de 300 segundos primero.

#¿Es esta solución para ti?

  • Escenarios recomendados: Sitios web con un certificado SSL estable (como los de Let’s Encrypt con autorenovación) y que busquen cumplir con estándares de seguridad bancaria o e-commerce.
  • Contraindicaciones: Si tienes subdominios que no pueden usar HTTPS por algún motivo técnico o si tu sitio cambia de certificados frecuentemente de forma manual.

#Pros y Contras

  • Pros: Seguridad real frente a secuestros de sesión, ligera mejora en velocidad al evitar una redirección en el servidor y mejor valoración por parte de auditorías de seguridad.
  • Contras: Rigidez absoluta. Si algo falla con tu SSL, la web queda «ladrillo» para el usuario recurrente hasta que se solvente.

«HSTS no es una sugerencia, es una ley que el servidor dicta y el navegador obedece sin rechistar.»

— Consultor de Seguridad Cloud

Esto lo escribo en febrero de 2026 con WP 6.7.2. Si llegaste aquí seis meses después, revisa el changelog: el tratamiento de las cabeceras de seguridad en WordPress ha ido evolucionando y es posible que el core introduzca alguna opción nativa en el administrador próximamente.

Opción Función técnica Estado
max-age Tiempo de memoria del navegador 1 año (Recomendado)
includeSubDomains Extiende protección a subdominios Opcional / Riesgo
preload Inclusión en lista blanca global Solo para expertos

Para profundizar en el estándar, te recomiendo visitar el listado de precarga HSTS o la guía de MDN Web Docs.