Saltar al contenido

Cabeceras de seguridad en WordPress: HTTPS, HSTS y CSP paso a paso

Publicado el 07-10-20269 min de lecturaPor la redacción de SmoothSeen

Las cabeceras de seguridad en WordPress se añaden en el servidor, en la CDN o con un pequeño plugin que engancha en send_headers, porque WordPress no las envía en las páginas públicas. Empieza por forzar HTTPS y después añade HSTS con un max-age corto, nosniff, Referrer-Policy, protección contra iframes, Permissions-Policy y una CSP en modo informe.

Lo esencial

  • WordPress no envía cabeceras de seguridad en las páginas públicas; solo protege el acceso y el escritorio con X-Frame-Options y, desde la 6.9, también con CSP frame-ancestors.
  • El orden importa: primero HTTPS en las dos URL de Ajustes > Generales y una redirección 301 en el servidor; después HSTS con un max-age corto.
  • HSTS con preload obliga a HTTPS a todos los subdominios, exige un max-age de al menos un año y es muy difícil de deshacer.
  • Los scripts en línea de WordPress y de los plugins complican una CSP estricta: empieza con Content-Security-Policy-Report-Only.
  • Si no controlas el servidor, un mu-plugin con el hook send_headers añade las cabeceras desde PHP, pero no a los ficheros estáticos.

Para comprobarlo en tu web: Auditoría SEO

En esta página

Una cabecera de seguridad es una línea de la respuesta HTTP que le dice al navegador qué puede y qué no puede hacer con tu página: si debe ir siempre por HTTPS, si otra web puede meterla en un iframe o desde dónde puede cargar scripts. WordPress controla el HTML que genera y unas pocas cabeceras de su escritorio. El resto depende de dónde se sirva la web: el servidor, la CDN o el alojamiento. Esta guía explica qué trae WordPress, qué añadir, con qué valor y dónde.

¿Qué cabeceras de seguridad envía WordPress por sí solo?

Muy pocas, y casi ninguna en las páginas que ven tus visitantes. Esto es lo que hace el código del núcleo en la rama 7.1, la actual1:

Dónde
Pantalla de acceso y escritorio
Cabecera
X-Frame-Options: SAMEORIGIN y, desde la 6.9, Content-Security-Policy: frame-ancestors 'self'
Función de WordPress
send_frame_options_header()2
Dónde
Escritorio
Cabecera
Referrer-Policy: strict-origin-when-cross-origin
Función de WordPress
wp_admin_headers()1
Dónde
API REST y admin-ajax.php
Cabecera
X-Content-Type-Options: nosniff
Función de WordPress
send_nosniff_header() y el servidor REST1
Dónde
Páginas públicas
Cabecera
Ninguna de las anteriores
Función de WordPress
—

La conclusión práctica es que tus entradas, páginas y fichas salen sin HSTS, sin protección contra iframes y sin CSP salvo que alguien las añada. Si un análisis de cabeceras te las marca como ausentes, no es un fallo de tu tema: es lo normal en WordPress.

Paso 1: fuerza HTTPS en WordPress y en el servidor

Sin HTTPS, el resto de cabeceras sirve de poco: el navegador ignora HSTS si llega por HTTP3. El cambio tiene tres partes:

  1. El certificado. Lo instala el alojamiento o el servidor. Comprueba que https:// carga sin avisos antes de seguir.
  2. Las dos URL de WordPress. En Ajustes > Generales, cambia a https:// la Dirección de WordPress (URL) y la Dirección del sitio (URL). Si están definidas en wp-config.php con WP_SITEURL y WP_HOME, los campos salen bloqueados y hay que cambiarlas allí4. Desde la 5.7, la Salud del sitio ofrece además un botón para pasar todo el sitio a HTTPS cuando detecta que el servidor lo admite, y sustituye al vuelo las URL http:// del contenido5.
  3. La redirección 301 en el servidor. WordPress redirige algunas URL, pero las imágenes, el CSS y cualquier fichero que sirva el servidor directamente no pasan por PHP. La redirección de http a https va en el servidor: tienes el paso a paso en las guías de .htaccess con HTTPS y HSTS en Apache y de HTTPS y HSTS en Nginx.

Para el acceso y el escritorio, la documentación de WordPress propone la constante FORCE_SSL_ADMIN en wp-config.php, que obliga a que el acceso y las sesiones de administración vayan por HTTPS6. Si un proxy inverso o una CDN terminan el TLS y te reenvían la petición por HTTP, la misma página documenta cómo marcar la petición como segura para evitar un bucle de redirecciones6. Esta es su versión, con una comprobación añadida para que no dé un aviso si la cabecera no llega:

define( 'FORCE_SSL_ADMIN', true );

// Solo si un proxy de confianza termina el TLS y te llega por http.
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] )
	&& false !== strpos( $_SERVER['HTTP_X_FORWARDED_PROTO'], 'https' ) ) {
	$_SERVER['HTTPS'] = 'on';
}

Úsalo solo si de verdad hay un proxy delante: cualquiera puede enviar X-Forwarded-Proto si el servidor es accesible directamente.

Paso 2: qué cabeceras añadir y con qué valor

Esta tabla resume un punto de partida razonable para un WordPress, con los valores que documenta MDN:

Cabecera
Strict-Transport-Security
Valor inicial
max-age=300 y, cuando todo vaya bien, max-age=31536000
Para qué sirve
Obliga al navegador a usar HTTPS en tus visitas siguientes
Cuidado con
Solo cuenta si llega por HTTPS3
Cabecera
X-Content-Type-Options
Valor inicial
nosniff
Para qué sirve
Impide que el navegador adivine el tipo de un fichero
Cuidado con
Los ficheros tienen que servirse con su tipo correcto
Cabecera
Referrer-Policy
Valor inicial
strict-origin-when-cross-origin
Para qué sirve
Limita lo que se envía como página de origen a otras webs
Cuidado con
Es el valor por defecto de los navegadores actuales7; declararlo lo deja fijado
Cabecera
X-Frame-Options
Valor inicial
SAMEORIGIN
Para qué sirve
Impide que otra web meta la tuya en un iframe
Cuidado con
ALLOW-FROM está obsoleto; para listas de orígenes usa frame-ancestors8
Cabecera
Permissions-Policy
Valor inicial
camera=(), microphone=(), geolocation=()
Para qué sirve
Desactiva funciones del navegador que tu web no usa
Cuidado con
Si un plugin usa el mapa con tu ubicación, no vetes geolocation
Cabecera
Content-Security-Policy-Report-Only
Valor inicial
Una política de prueba (ver más abajo)
Para qué sirve
Avisa de lo que bloquearía una CSP sin bloquear nada9
Cuidado con
No admite sandbox ni se puede poner en una etiqueta meta9

Dos cabeceras que no conviene añadir:

  • X-XSS-Protection: 1. MDN recomienda usar CSP en su lugar y avisa de que esta cabecera puede crear vulnerabilidades en webs que eran seguras10. Si tu alojamiento la pone, el valor menos arriesgado es 0.
  • HSTS con preload el primer día. Para entrar en la lista de precarga de los navegadores hace falta includeSubDomains y un max-age de al menos un año, y salir de esa lista es muy difícil3. Afecta a todos los subdominios, también al que aún no tiene certificado. Llega a ello solo cuando lleves meses con HSTS sin problemas.

X-Frame-Options frente a frame-ancestors

Las dos impiden que otra web cargue la tuya en un iframe. X-Frame-Options es la antigua y solo admite DENY o SAMEORIGIN; la directiva frame-ancestors de CSP es la moderna y admite una lista de orígenes8. WordPress envía ya las dos en el acceso y el escritorio2. En las páginas públicas, mientras tu CSP siga en modo informe, mantén X-Frame-Options: SAMEORIGIN, porque frame-ancestors dentro de una política Report-Only avisa pero no protege.

¿Por qué una CSP estricta es difícil en WordPress?

Una CSP (Content Security Policy) es la lista de orígenes desde los que la página puede cargar scripts, estilos, imágenes o marcos. Por defecto, si la política incluye script-src, el navegador no ejecuta JavaScript en línea, y MDN advierte de que 'unsafe-inline' anula buena parte del sentido de tener una CSP11.

En WordPress hay mucho JavaScript en línea: el que imprime el núcleo, el de los temas y el de casi cualquier plugin de formularios, analítica o cookies. Desde la 5.7, WordPress tiene funciones y filtros para añadir atributos a las etiquetas de script que imprime, y su anuncio las presentaba como un camino hacia una CSP en el núcleo, los plugins y los temas12. Pero los plugins que escriben su propio <script> no pasan por ahí.

Por eso el orden sensato es este:

  1. Publica la política como Content-Security-Policy-Report-Only. No bloquea nada.
  2. Navega por la web con las herramientas de desarrollo abiertas: cada infracción aparece en la consola. Si quieres recibir los informes, declara un destino con Reporting-Endpoints y la directiva report-to9.
  3. Ajusta la política hasta que las páginas importantes no den avisos.
  4. Solo entonces cámbiala a Content-Security-Policy. Ten en cuenta que, si hay dos políticas, el navegador aplica las dos y gana la más restrictiva11.

Dónde poner las cabeceras: servidor, CDN o PHP

Dónde
Servidor web (.htaccess en Apache, add_header en Nginx)
Ventajas
Cubre todo, también imágenes, CSS y JS; no depende de PHP
Inconvenientes
Necesitas acceso a la configuración
Dónde
CDN o proxy
Ventajas
Se gestiona desde un panel, sin tocar el servidor
Inconvenientes
Solo protege lo que pasa por la CDN; mira la guía de cabeceras de seguridad en Cloudflare
Dónde
PHP, con el hook send_headers
Ventajas
Funciona en cualquier alojamiento
Inconvenientes
Solo llega a las páginas que genera WordPress en la parte pública

Si no puedes tocar el servidor ni la CDN, un mu-plugin es la opción más limpia. Los must-use plugins son ficheros PHP en wp-content/mu-plugins/ que WordPress carga siempre y que no se pueden desactivar desde el escritorio13. La acción send_headers sirve para añadir cabeceras a la respuesta y, desde la 6.1, se ejecuta después de la consulta principal, así que admite etiquetas condicionales14. Guarda esto como wp-content/mu-plugins/cabeceras-seguridad.php:

<?php
/**
 * Plugin Name: Cabeceras de seguridad
 * Description: Añade cabeceras de seguridad a las páginas que genera WordPress.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

add_action( 'send_headers', function () {
	if ( headers_sent() ) {
		return;
	}

	// HSTS solo por HTTPS (por HTTP el navegador la ignora).
	// Empieza con 5 minutos; súbelo a 31536000 cuando todo vaya por https.
	if ( is_ssl() ) {
		header( 'Strict-Transport-Security: max-age=300' );
	}

	header( 'X-Content-Type-Options: nosniff' );
	header( 'Referrer-Policy: strict-origin-when-cross-origin' );
	header( 'X-Frame-Options: SAMEORIGIN' );
	header( 'Permissions-Policy: camera=(), microphone=(), geolocation=()' );

	// CSP en modo informe: no bloquea nada, solo avisa en la consola.
	header(
		"Content-Security-Policy-Report-Only: default-src 'self'; "
		. "script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; "
		. "img-src 'self' data: https:; font-src 'self' data:; "
		. "frame-ancestors 'self'; object-src 'none'; base-uri 'self'"
	);
} );

La CSP de ejemplo es un punto de partida, no una política segura: lleva 'unsafe-inline' para que puedas ver primero qué más carga tu web. Si usas fuentes, vídeos o analítica de otros dominios, la consola te dirá cuáles añadir.

Tres límites de esta vía:

  • No cubre los ficheros estáticos (imágenes, CSS, JS) que entrega el servidor sin pasar por WordPress, ni el escritorio.
  • Una caché de página puede saltársela. Si tu caché sirve el HTML guardado sin ejecutar PHP, las cabeceras pueden no salir en las páginas cacheadas. Compruébalo con curl en una página que ya esté en caché.
  • Una cabecera, un sitio. Si el servidor ya pone X-Frame-Options y el mu-plugin también, acabarás con valores duplicados. Elige dónde vive cada cabecera.

Cómo comprobarlo

Empieza por pedir las cabeceras de una página pública y de una imagen. Si la página las lleva y la imagen no, las estás poniendo desde PHP:

curl -sI https://www.ejemplo.es/
curl -sI https://www.ejemplo.es/wp-content/uploads/2026/10/foto.jpg

Después:

  1. Pasa la portada por el HTTP Observatory de Mozilla, que revisa las cabeceras de seguridad y la redirección a HTTPS15.
  2. Abre la consola del navegador en tus páginas clave y busca avisos de la CSP en modo informe.
  3. Revisa en Herramientas > Salud del sitio que no haya avisos de HTTPS.

Qué hace SmoothSeen con esto

SmoothSeen comprueba en cada análisis si la página va por HTTPS, si http redirige a https y qué cabeceras de seguridad envía, usando el HTTP Observatory de Mozilla. El resultado entra en la nota de Posicionamiento web y, si falta algo, aparece como tarea en el plan de acción con el motivo.

Qué hacer esta semana

Haz el curl -I a tu portada y anota qué cabeceras faltan. Si tienes acceso al servidor, añádelas allí; si no, instala el mu-plugin con HSTS a cinco minutos y la CSP en modo informe, y revisa la consola durante unos días. Para ver el resultado junto al resto de comprobaciones técnicas, analiza tu web con SmoothSeen.

Preguntas frecuentes

¿Necesito un plugin de seguridad para añadir cabeceras en WordPress?

No. Un plugin de seguridad puede hacerlo, pero también lo hace el servidor, la CDN o un mu-plugin de veinte líneas que controlas tú. Lo importante es que cada cabecera se defina en un único sitio, porque varios plugins o capas añadiendo la misma cabecera producen valores duplicados que cuesta depurar. Si ya tienes un plugin que las gestiona, revisa sus valores con curl -I.

¿Cuándo puedo subir HSTS a un año?

Cuando lleves al menos unos días con un max-age corto sin ningún problema: todas las páginas cargan por HTTPS, no hay contenido mixto y los subdominios que usas tienen certificado. Entonces sube a 31536000 segundos. Añadir includeSubDomains o preload es otra decisión, porque afecta a todos los subdominios y la precarga es muy difícil de retirar.

¿Por qué mi CSP rompe el escritorio de WordPress?

Porque probablemente la has puesto en el servidor para todo el dominio, incluido /wp-admin/, y el escritorio y el editor de bloques usan JavaScript y estilos en línea. El mu-plugin de esta guía no tiene ese problema porque send_headers no se ejecuta en el escritorio. Si la configuras en el servidor, limítala a la parte pública o pruébala antes en modo Report-Only.

¿Sigue haciendo falta FORCE_SSL_ADMIN si todo el sitio ya va por HTTPS?

Con las dos URL en https:// y la redirección en el servidor, el escritorio ya va por HTTPS en la práctica. La constante añade una garantía: WordPress fuerza HTTPS en el acceso y las sesiones de administración aunque falle otra capa. Es una línea en wp-config.php y la documentación oficial la sigue proponiendo, así que vale la pena dejarla puesta.

Fuentes

  1. 1Código fuente de WordPress 7.1: default-filters.php, admin-filters.php y functions.php, WordPress (repositorio oficial wordpress-develop), consultado el 07-10-2026.
  2. 2send_frame_options_header(), WordPress Developer Resources, consultada el 07-10-2026.
  3. 3Strict-Transport-Security, MDN Web Docs, consultada el 07-10-2026.
  4. 4Settings General screen, WordPress.org Documentation, actualizada el 03-07-2026.
  5. 5Improved HTTPS detection and migration in WordPress 5.7, Make WordPress Core, 22-02-2021.
  6. 6HTTPS, WordPress Developer Resources, actualizada el 29-09-2025.
  7. 7Referrer-Policy, MDN Web Docs, consultada el 07-10-2026.
  8. 8X-Frame-Options, MDN Web Docs, consultada el 07-10-2026.
  9. 9Content-Security-Policy-Report-Only, MDN Web Docs, consultada el 07-10-2026.
  10. 10X-XSS-Protection, MDN Web Docs, consultada el 07-10-2026.
  11. 11Content-Security-Policy, MDN Web Docs, consultada el 07-10-2026.
  12. 12Introducing script attributes related functions in WordPress 5.7, Make WordPress Core, 23-02-2021.
  13. 13Must Use Plugins, WordPress Developer Resources, actualizada el 23-09-2026.
  14. 14send_headers (hook), WordPress Developer Resources, consultada el 07-10-2026.
  15. 15HTTP Observatory, MDN (Mozilla), consultada el 07-10-2026.

Cómo citar este artículo

SmoothSeen. (2026, 7 de octubre). Cabeceras de seguridad en WordPress: HTTPS, HSTS y CSP paso a paso. https://smoothseen.com/es/blog/wordpress-cabeceras-seguridad/

Quién lo escribe

SmoothSeen es una herramienta de auditoría web que mide el posicionamiento en buscadores y en asistentes de IA y entrega informes con la marca de la agencia.

Este blog es de SmoothSeen: cuando un artículo habla del producto, lo hace sabiendo que es el nuestro. Las cifras de terceros enlazan a su fuente original.

Historial de cambios

  • Primera versión.

Sigue leyendo

Cabeceras de seguridad en WordPress: HTTPS, HSTS y CSP