secaudit.eu
Protección

HTTPS en WordPress: contenido mixto y redirecciones

HTTPS en WordPress bien hecho: certificados gratuitos, sustitución segura de URL con WP-CLI, una sola redirección 301, bucles con proxy, contenido mixto y caducidad.

Por , AngelForce OÜ 8 min de lectura

También en: English Deutsch Français Italiano Polski Português Türkçe

La mayoría de los problemas de HTTPS en WordPress vienen de una migración a medias, no de la falta de un certificado. El certificado está instalado y la página de inicio muestra el candado. Pero las entradas del blog enseñan un icono de advertencia, en el contenido siguen quedando enlaces http:// antiguos y quien escribe example.com pasa por dos o tres redirecciones antes de llegar a la página real. Esta guía corrige ese estado siguiendo un orden seguro.

HTTPS en WordPress: el certificado es solo el primer paso

Empiece midiendo. Estos dos comandos muestran por qué pasa el navegador de un visitante:

curl -sI http://example.com
curl -sIL http://example.com | grep -iE '^(HTTP|location)'

El primer comando muestra el código de estado y la cabecera Location de la primera respuesta. El segundo sigue todas las redirecciones. Si ve más de un 301 antes del 200 final, tiene una cadena de redirecciones. Después abra el sitio en el navegador, pulse F12 y mire la consola: ahí aparecen las advertencias de contenido mixto.

Conviene también tener claro qué hace HTTPS. Cifra el tráfico entre el navegador y el servidor y lo protege frente a modificaciones en tránsito. Es una de las medidas que cita el artículo 32, apartado 1, letra a), del RGPD: el cifrado, aplicado a contraseñas de acceso, formularios de contacto y datos de pago. Pero no dice nada sobre si el sitio en sí es seguro. Un sitio con certificado válido puede seguir ejecutando un plugin vulnerable, alojar malware o tener una cuenta de administrador protegida con password123. Cómo encaja el cifrado con el resto de medidas de seguridad se explica en Artículo 32 del RGPD para WordPress.

Diagrama: tres puntos de entrada HTTP y www redirigen cada uno con un único 301 a una sola URL HTTPS canónica
Cada variante antigua de la URL debe llegar a la dirección HTTPS canónica en un solo salto

Certificado gratuito de su hosting o mediante ACME

La mayoría de los paneles de hosting europeos ofrecen un certificado gratuito de Let's Encrypt con un solo interruptor, a menudo en «SSL/TLS» o «Seguridad». Actívelo y compruebe que cubre tanto example.com como www.example.com. Un certificado para un solo nombre provoca errores en el navegador con el otro, aunque ese otro solo redirija.

En un servidor propio, use un cliente ACME. Certbot es la opción habitual y configura la renovación automática:

sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run

Use --apache en lugar de --nginx si trabaja con Apache. La simulación (--dry-run) comprueba que la renovación funcionará de verdad. Si falla ahora, fallará también en la próxima renovación real.

No hace falta pagar por un certificado de validación de dominio para tener el candado. Los certificados de pago tienen sentido por contratos de soporte o necesidades de validación concretas. Para el cifrado, uno gratuito es igual de fuerte.

Copia de seguridad y cambio de la dirección de WordPress y del sitio

Haga una copia de la base de datos antes de tocar nada. Los pasos siguientes reescriben miles de filas y la copia es su botón de deshacer. Copias de seguridad de WordPress que sí se restauran explica cómo hacer copias en las que pueda confiar. Con WP-CLI basta una línea:

wp db export before-https.sql

Después vaya a Ajustes > Generales y cambie tanto Dirección de WordPress (URL) como Dirección del sitio (URL) de http:// a https://. Si WordPress está instalado en un subdirectorio, conserve la ruta. También puede hacerlo desde la línea de comandos:

wp option update home 'https://example.com'
wp option update siteurl 'https://example.com'

Si los dos campos aparecen en gris, WP_HOME y WP_SITEURL están definidos en wp-config.php. Cambie allí los valores: los ajustes del escritorio no pueden sobrescribirlos.

Si se queda sin acceso y no puede volver a iniciar sesión, por ejemplo porque el certificado aún no funciona, defina temporalmente WP_HOME y WP_SITEURL en wp-config.php con la antigua dirección http:// (o devuélvalos a ese valor si ya estaban), o ejecute los dos comandos wp option update con los valores antiguos. Arregle primero el certificado y vuelva a intentarlo.

Sustituir las URL http:// antiguas con wp search-replace

Sus entradas, menús, widgets y opciones del tema siguen conteniendo cientos de enlaces http://example.com. No los corrija con un REPLACE de SQL a pelo. WordPress y muchos plugins guardan sus ajustes como PHP serializado, que registra la longitud de cada cadena, por ejemplo s:22:"http://example.com/img". Al añadir la «s», la cadena pasa a tener un carácter más. La longitud almacenada ya no coincide, PHP no puede leer el valor y los widgets, los diseños del maquetador o los ajustes del tema desaparecen sin avisar.

[wp search-replace](https://developer.wordpress.org/cli/commands/search-replace/) deserializa los datos, sustituye el texto y vuelve a serializar con las longitudes correctas. Ejecute siempre antes una simulación:

wp search-replace 'http://example.com' 'https://example.com' --all-tables --skip-columns=guid --dry-run

Revise los recuentos por tabla. Si parecen razonables, ejecute el mismo comando sin --dry-run. Algunas observaciones:

  • --skip-columns=guid deja intactos los GUID de las entradas. Son identificadores, no enlaces, y por convención no se modifican.
  • --all-tables afecta a todas las tablas de la base de datos. Si la base de datos se comparte con otro sitio o aplicación, use en su lugar --all-tables-with-prefix.
  • Si su host canónico es sin www, haga una segunda sustitución de http://www.example.com a https://example.com.
  • Algunos maquetadores guardan JSON con barras escapadas (http:\/\/example.com), que una búsqueda simple no encuentra. Haga una simulación con esa forma o use la herramienta de sustitución de URL del propio maquetador.

Después, vacíe todas las cachés: wp cache flush, su plugin de caché de páginas, cualquier caché del servidor y la CDN. Regenere los archivos CSS del maquetador si ofrece esa opción. Sin acceso por SSH, un plugin de búsqueda y reemplazo que maneje datos serializados, como Better Search Replace, hace el mismo trabajo. Elimínelo cuando termine.

Una sola redirección 301 al host HTTPS canónico

Elija una dirección canónica, con o sin www, y manténgala. Todas las demás variantes deben ir directamente a ella con una sola redirección 301. Una cadena como http → https → www → final ralentiza cada primera visita, desperdicia rastreos de los buscadores y hace difícil localizar los errores.

Apache, colocado encima del bloque # BEGIN WordPress en .htaccess:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

nginx:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name www.example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    return 301 https://example.com$request_uri;
}

Mantenga la redirección en un único sitio. Si un plugin, .htaccess y la CDN redirigen a la vez, aparecen cadenas o bucles. Elija el servidor o la CDN y elimine el resto.

Bucles de redirección tras una CDN o un proxy inverso

El bucle clásico es el modo SSL «Flexible» de Cloudflare. El navegador habla HTTPS con Cloudflare, pero Cloudflare habla HTTP sin cifrar con su servidor. El servidor ve HTTP, redirige a HTTPS y el ciclo se repite. Instale un certificado en el servidor y ponga el modo en Full (strict) en los ajustes SSL/TLS de Cloudflare. Así el tráfico hacia el servidor va cifrado y se valida el certificado del servidor.

Otros proxies y balanceadores de carga transmiten el esquema original en una cabecera X-Forwarded-Proto. WordPress no la lee por defecto. Añada esto encima de la línea «stop editing» de wp-config.php:

if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
    $_SERVER['HTTPS'] = 'on';
}

FORCE_SSL_ADMIN y la página de acceso

define( 'FORCE_SSL_ADMIN', true );

Con esto WordPress sirve la página de acceso y el escritorio solo por HTTPS. Las contraseñas y las cookies de administración nunca viajan sin cifrar, aunque alguien abra un marcador antiguo con http://. Es una red de seguridad, no su solución de redirección: no hace nada por las páginas públicas. Otros ajustes de wp-config.php se tratan en Endurecimiento de wp-config.php: 10 ajustes que revisar.

Localizar el contenido mixto restante con las herramientas de desarrollo

Hay contenido mixto cuando una página HTTPS carga un recurso por HTTP. Los navegadores bloquean los scripts y marcos inseguros y avisan de las imágenes o las actualizan, y por eso desaparece el candado. Abra las herramientas de desarrollo en una página afectada. La consola enumera cada petición insegura con su URL. En los navegadores basados en Chromium, escriba scheme:http en el filtro de la pestaña Red para verlas todas de una vez.

Tras una sustitución limpia, las causas restantes suelen estar fuera de la base de datos. Las fuentes típicas son URL escritas a mano en archivos del tema, widgets de HTML personalizado, CSS propio (background: url(http://...)), archivos CSS del maquetador y antiguos contenidos incrustados de terceros. Para localizarlas en el tema:

grep -rn "http://" wp-content/themes/your-theme/
wp db search 'http://example.com'

Corrija el problema en su origen. Los plugins que reescriben las URL en cada carga de página esconden el problema sin resolverlo y dejan de funcionar al desactivarlos. La directiva CSP upgrade-insecure-requests puede servir de puente temporal mientras limpia. Se explica en Cabeceras de seguridad de WordPress.

Compruebe algo más que la página de inicio. Pruebe el proceso de compra, el formulario de contacto, la página de acceso, una entrada del blog, un archivo de categoría y cualquier página de destino construida con otra plantilla.

Vigilar la caducidad del certificado y activar HSTS después

La renovación automática puede fallar sin que nadie se dé cuenta. Las causas habituales son un cambio de DNS, el paso a una CDN nueva, o una regla de cortafuegos o de redirección que bloquea /.well-known/acme-challenge/. Configure un monitor externo que compruebe el certificado y le avise al menos dos semanas antes de que caduque. Muchos servicios de monitorización de disponibilidad incluyen esta comprobación. Para consultar usted mismo la fecha de caducidad:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate

HSTS (RFC 6797) va en último lugar. Indica a los navegadores que usen solo HTTPS, de modo que un certificado defectuoso se convierte en un error bloqueante para los visitantes y, con includeSubDomains, también cualquier subdominio olvidado que solo funcione por HTTP. Actívelo solo cuando todos los subdominios y redirecciones funcionen, y empiece con un max-age corto. Los valores y la advertencia sobre preload se tratan en Cabeceras de seguridad de WordPress.

El plugin de auditoría de secaudit.eu revisa los ajustes de endurecimiento y configuración, además de la integridad de los archivos y los plugins desactualizados. Tras la migración, dispone de un registro del estado del sitio que puede conservar para su documentación. → secaudit.eu

Siguiente paso: ejecute la comprobación de saltos con curl -sIL sobre las cuatro variantes (http, http://www, https://www, https). Después abra sus cinco páginas más importantes con la consola de las herramientas de desarrollo abierta. A lo sumo un 301 por variante, un 200 directo en la URL HTTPS canónica y ningún mensaje de contenido mixto indican que la migración está completa.

FAQ

¿Basta un certificado gratuito para una tienda online?

Sí. Un certificado gratuito de validación de dominio cifra el tráfico igual de bien que uno de pago. La seguridad de la tienda depende de sus plugins, actualizaciones, accesos y configuración de pagos, no del precio del certificado.

¿Por qué desaparece el candado solo en algunas páginas?

Esas páginas cargan al menos un recurso por HTTP. Suele ser una imagen, un script o un contenido incrustado de un widget, una plantilla o una sección del maquetador que las demás páginas no usan. La consola de las herramientas de desarrollo en esa página muestra la URL exacta.

¿Hace HTTPS que mi sitio cumpla el RGPD?

No. HTTPS es una medida técnica del artículo 32: el cifrado en tránsito. El RGPD también espera que proteja los propios sistemas, restablezca los datos tras incidentes, pruebe sus medidas con regularidad y documente todo ello.

Este artículo es información general y no constituye asesoramiento jurídico.

Compruebe su propio sitio

Security Audit & Compliance es el plugin de WordPress de secaudit.eu: busca malware, spam oculto, archivos del núcleo modificados y código vulnerable, y relaciona sus hallazgos con el art. 32 del RGPD, el art. 21 de NIS2 y el OWASP Top 10.

Ver qué comprueba el plugin
Melike Görel

Melike Görel escribe las guías de secaudit.eu sobre seguridad de WordPress y cumplimiento normativo europeo para AngelForce OÜ, la empresa de software de Tallin que está detrás de secaudit.eu.

Elaborado con ayuda de IA y verificado antes de su publicación. Este artículo es información general, no asesoramiento jurídico.