VoryngVoryng
VoryngVoryng

Cómo configurar las cabeceras de seguridad en WordPress

En WordPress hay tres formas de hacerlo y la más recomendada por internet es la que falla en silencio. Si tienes un plugin de caché —y lo tienes— las cabeceras que añadas desde PHP no llegan a la mayoría de tus visitantes.

Actualizada el 6 de octubre de 2026

La forma que funciona: a nivel de servidor

Si configuras las cabeceras en el servidor, se aplican a todo: páginas cacheadas, imágenes, el admin y las respuestas de error. Es la opción correcta en casi todos los casos. Primero averigua qué servidor tienes:

curl -sI https://tu-dominio.com | grep -i "^server:"

Si es Apache (hosting compartido, cPanel, Plesk)

Añade esto al .htaccess de la raíz, fuera del bloque que WordPress gestiona entre los comentarios # BEGIN WordPress y # END WordPress.

.htaccess
<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>

Si es nginx

nginx no lee .htaccess, así que no hay nada que puedas hacer desde el gestor de ficheros. Necesitas acceso a la configuración del servidor o pedírselo al hosting. Si gestionas el servidor, nuestra guía de nginx cubre el caso completo, incluida la trampa de herencia de add_header. Si es hosting compartido, esto es literalmente lo que tienes que pedir al soporte:

petición al soporte del hosting
Buenos días:

¿Podrían añadir estas cabeceras de respuesta al bloque server de mi sitio?

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

Gracias.

Con un plugin

Si no tienes acceso al servidor y no quieres depender del soporte, un plugin es una opción razonable. Los que gestionan cabeceras de forma visual son del tipo «HTTP Headers» o «WP Headers & Redirects».

  • Arrastra la misma limitación de caché que functions.php: si la página se sirve de caché, el plugin no corre.
  • Algunos plugins de caché tienen su propia sección de cabeceras, que sí se aplica a lo cacheado. Si usas LiteSpeed Cache o WP Rocket, mira ahí antes de instalar nada.
  • Un plugin más es una dependencia más que mantener. Si puedes tocar el servidor, hazlo en el servidor.

functions.php, si no queda otra

Válido solo si el sitio no tiene caché de página. Ponlo en un plugin propio o en el functions.php de un tema hijo, nunca en el del tema: una actualización se lo lleva.

tema hijo — functions.php
add_action('send_headers', function () {
  if (is_admin()) return;
  header('Strict-Transport-Security: max-age=31536000; includeSubDomains');
  header('X-Content-Type-Options: nosniff');
  header('X-Frame-Options: SAMEORIGIN');
  header('Referrer-Policy: strict-origin-when-cross-origin');
  header('Permissions-Policy: camera=(), microphone=(), geolocation=()');
});

Dos conflictos propios de WordPress

  • Plugins de seguridad como Wordfence o iThemes ya envían algunas de estas cabeceras. Si las duplicas con valores distintos, el navegador recibe las dos y el resultado depende de la cabecera. Comprueba qué se está enviando ya antes de añadir.
  • X-Frame-Options en DENY rompe cualquier cosa que incruste tu web en un iframe, incluidas pasarelas de pago, previsualizaciones de Elementor y algunos constructores. SAMEORIGIN es el valor sensato por defecto.

Verificar como un visitante, no como administrador

Este es el paso que casi todo el mundo se salta y es el que importa. Hazlo desde la terminal, sin sesión y sin cookies:

curl -sI https://tu-dominio.com | grep -i -E "strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy"

Si desde el navegador con la sesión abierta las ves y con curl no, es exactamente el problema de la caché: estás mirando una página generada por PHP y tus visitantes reciben la copia estática. Vacía la caché, vuelve a lanzar el curl y, si siguen sin salir, pasa al método de servidor.

Content-Security-Policy en WordPress

Déjala para el final y no la copies de ningún sitio. Un WordPress con un constructor visual, Google Fonts, analítica y una pasarela de pago carga scripts de muchos orígenes, y una CSP copiada rompe el editor antes de romper la web pública. Empieza en Content-Security-Policy-Report-Only, navega el sitio y el admin unos días mirando la consola, añade los orígenes legítimos que aparezcan y solo entonces actívala de verdad.

Otras guías

Cómo configurar las cabeceras de seguridad en WordPress | Voryng