En pocas palabras: Las cabeceras HTTP de seguridad en <```html a href="https://seguridadenwordpress.com/guia-wordpress/">WordPress se configuran en el servidor vía .htaccess, nginx.conf o wp-config.php, y cubren cuatro frentes: Content-Security-Policy contra XSS, Strict-Transport-Security para forzar HTTPS, X-Frame-Options contra clickjacking y Referrer-Policy. Bien implementadas, alcanzan calificación A+ en securityheaders.com.
Las cabeceras HTTP de seguridad en WordPress se configuran a nivel de servidor (vía .htaccess, nginx.conf o wp-config.php) o con un plugin dedicado, y cubren cuatro frentes: CSP contra XSS, HSTS para forzar HTTPS, X-Frame-Options contra clickjacking y complementos como Referrer-Policy. Bien puestas, alcanzan una calificación A+ en securityheaders.com en una tarde de trabajo.
Las cabeceras HTTP de seguridad son instrucciones que el servidor agrega a cada respuesta HTTP para limitar lo que el navegador puede hacer con tu sitio: qué scripts ejecuta, si la página puede mostrarse dentro de un iframe ajeno y si debe conectarse siempre por HTTPS. En WordPress se implementan con Content-Security-Policy, Strict-Transport-Security y X-Frame-Options, entre otras, todas documentadas por MDN Web Docs y por el proyecto Secure Headers de OWASP.
En 30 segundos
- Son reglas del servidor, no del navegador. Tu hosting manda la cabecera en cada respuesta y el navegador la obedece; no hay nada que instalar del lado del visitante.
- CSP bloquea XSS. Con script-src definís qué dominios pueden servir JavaScript; todo lo demás, el navegador lo rechaza.
- HSTS mata el downgrade a HTTP. Un max-age de 31536000 (un año) obliga al navegador a usar HTTPS sin excepciones.
- X-Frame-Options frena el clickjacking. DENY o SAMEORIGIN impiden que otro sitio incruste tus páginas en un iframe invisible; el reemplazo moderno es frame-ancestors dentro de la CSP.
- Verificar es gratis. SecurityHeaders.com califica tu dominio de A+ a F, y curl -I te muestra los headers crudos desde la terminal.
¿Qué son las cabeceras HTTP de seguridad y por qué importan en WordPress?
Son metadatos que viajan en la respuesta HTTP, antes del HTML, y le dicen al navegador cómo comportarse con tu contenido. Importan en WordPress por un motivo simple: el CMS mueve más del 40% de la web según W3Techs, y su ecosistema de plugins mete scripts de terceros en millones de sitios. Si nadie define reglas, cualquier script inyectado corre sin restricciones.
La diferencia clave: el código de tu tema vive en el servidor, pero la ejecución pasa en el navegador del visitante. Las cabeceras son el contrato entre ambos. Sin ese contrato, estás expuesto a XSS (scripts ajenos corriendo en tu dominio), clickjacking (tu página disfrazada dentro de un iframe) y downgrades a HTTP aunque tengas certificado instalado.
| Escenario de ataque | Sin cabeceras | Con cabeceras bien configuradas |
|---|---|---|
| Script malicioso inyectado vía plugin vulnerable | El navegador lo ejecuta sin preguntas | La CSP lo bloquea si el dominio no está en tu lista blanca |
| Tu login incrustado en un iframe de phishing | El usuario clickea un botón falso montado sobre el real | X-Frame-Options o frame-ancestors niegan el encastre |
| Visitante que escribe tudominio.com sin https | Navega sin cifrado hasta que un redirect lo salva | HSTS fuerza HTTPS desde el navegador, sin depender del redirect |

¿La buena noticia? Todo esto se resuelve con unas líneas en el servidor. (Que no es poco, viniendo del mundo WordPress, donde cada arreglo suele costar tres plugins y un sacrificio.)
¿Cómo funciona Content-Security-Policy en un sitio WordPress?
Ponele que tenés una tienda en WooCommerce y un proveedor de reservas carga su widget desde su propio dominio. Un día activás una CSP copiada de un tutorial, con default-src ‘self’, y el widget desaparece. ¿Qué pasó? La política le dijo al navegador que solo aceptara recursos de tu dominio, y el widget venía de otro. Eso es exactamente lo que hace la CSP: dibuja la lista blanca de todo lo que tu página puede cargar.
- default-src: la política base para todos los recursos; si no definís algo más específico, rige esa.
- script-src: de dónde puede venir JavaScript. Acá se juega la mayor parte de la protección contra XSS.
- style-src: ídem para CSS. Ojo, porque los constructores visuales inyectan estilos inline a diario.
- img-src: imágenes, incluyendo data: si usás SVG embebidos.
- frame-src: qué iframes podés mostrar: YouTube, pasarelas de pago, mapas.
- frame-ancestors: quién puede incrustarte a vos, el reemplazo moderno de X-Frame-Options.
Dos ejemplos reales. Un blog con GA4 necesita script-src ‘self’ https://www.googletagmanager.com y su correspondiente connect-src para los hits. Una tienda con Mercado Pago suma sdk.mercadopago.com en script-src y frame-src; con Stripe, js.stripe.com. Cada servicio externo que cargues es un origen que tenés que anotar. Te puede servir nuestra cobertura de autenticación sin contraseñas usando passkeys.
Los conflictos conocidos en WordPress vienen por el lado de Elementor (montañas de CSS inline que exigen style-src ‘unsafe-inline’) y de reCAPTCHA, que reparte peticiones entre google.com y gstatic en varios frentes. Lo ideal sería firmar cada script con nonces o hashes, pero WordPress no firma sus scripts inline por defecto, así que muchos terminan con unsafe-inline global. Funciona, pero es una CSP «de adorno»: levanta la barrera sin cerrar la puerta.
Antes de activar nada en firme, tenés Content-Security-Policy-Report-Only: misma sintaxis, pero no bloquea nada, solo reporta violaciones en la consola. ¿Y qué pasó cuando alguien lo saltó y mandó la CSP directa a producción? Exacto: el slider del home dejó de existir. Usá Report-Only una semana, siempre.
¿Para qué sirve HSTS en WordPress y cómo se activa?
Strict-Transport-Security es una cabecera que le ordena al navegador usar solo HTTPS con tu dominio durante el tiempo que indiques en max-age, medido en segundos. Una vez recibida, el navegador ni siquiera intenta HTTP: redirige internamente antes de tocar la red. Según la referencia de MDN, es la defensa estándar contra downgrade attacks y robo de cookies en redes abiertas.
- max-age: cuántos segundos dura la política. 31536000 equivale a un año, el valor mínimo que exige la lista de preload de Chromium.
- includeSubDomains: extiende la regla a todos los subdominios. Si blog.tudominio.com todavía navega en HTTP, se rompe.
- preload: habilita el envío a la lista precargada de Chrome, Firefox y Edge, para que hasta el primer visitante evite HTTP.
Ojo con esto: HSTS es difícil de revertir. Suena exagerado, no lo es. El navegador guarda la política en caché local; si mañana quitás la cabecera, los visitantes que ya la recibieron siguen forzando HTTPS hasta cumplir el max-age. Y si enviaste la versión con preload, salir de la lista de Chromium toma meses.
El camino prudente: verificá que el certificado cubra el dominio y todos los subdominios, arrancá con un max-age chico (300 segundos), mirá que nada se rompa, y recién ahí subí a un año. La cabecera protege al visitante recurrente; la lista de preload protege también al primero. Son cosas distintas, y conviene activarlas en ese orden.
X-Frame-Options vs frame-ancestors: ¿cuál conviene contra el clickjacking?
Contra clickjacking, hoy conviene frame-ancestors dentro de la CSP, porque permite listar orígenes específicos; X-Frame-Options sobrevive como cabecera de compatibilidad con solo dos valores útiles. El ataque es simple: el atacante incrusta tu página en un iframe transparente sobre un señuelo, y el usuario clickea creyendo que aprieta otro botón. Clásico: aprobar un pago o borrar una cuenta sin enterarse.
| Valor | Comportamiento | Estado en 2026 |
|---|---|---|
| DENY | Nadie puede incrustar la página, ni vos mismo | Vigente |
| SAMEORIGIN | Solo tu propio dominio puede incrustarla | Vigente; el más usado |
| ALLOW-FROM https://otro.com | Permitía un origen específico | Obsoleto: los navegadores lo retiraron |
| frame-ancestors (dentro de la CSP) | Lista flexible de orígenes permitidos | El reemplazo moderno recomendado |
Matiz que evita dolores de cabeza: X-Frame-Options protege tus páginas de ser incrustadas; no controla qué iframes vos mostrás (eso es frame-src). Si incrustás videos de YouTube, esta cabecera no te afecta. Y si tu checkout de WooCommerce vive en un subdominio distinto, SAMEORIGIN lo va a bloquear: en ese caso usá frame-ancestors con ambos orígenes. Tema relacionado: proteger la base de datos MySQL.
¿Cómo agregar cabeceras de seguridad en WordPress sin plugins?
Tenés cuatro caminos, y la elección depende de tu acceso al servidor: .htaccess en Apache, nginx.conf en Nginx, wp-config.php si querés que la configuración viaje con el sitio, o el hook send_headers desde functions.php. Todos llegan al mismo resultado; ninguno requiere plugin.
Opción 1: .htaccess (Apache). La más común en hostings compartidos. En un panel con cPanel, como los planes de DonWeb, entrás al Administrador de archivos, editás el .htaccess de la raíz y listo; estos entornos suelen traer mod_headers activo.
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src 'self' https://www.youtube-nocookie.com"
</IfModule>
Opción 2: nginx.conf (Nginx). Si administrás un VPS, agregá las cabeceras en el bloque server, con always al final para que se envíen también en respuestas de error. Trampa clásica de Nginx: si declarás cualquier add_header dentro de un location, el servidor deja de heredar los del bloque superior. Medio que te deja las cabeceras a medias sin avisar.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
Opción 3: wp-config.php. Pegá llamadas a header() al inicio del archivo, debajo de la apertura de PHP. Ventaja: la configuración viaja con el sitio en migraciones y no depende de que el hosting tenga mod_headers expuesto.
header("Strict-Transport-Security: max-age=31536000; includeSubDomains");
header("X-Frame-Options: SAMEORIGIN");
header("X-Content-Type-Options: nosniff");
Opción 4: functions.php con el hook send_headers. Útil si solo querés tocar el tema, aunque conviene hacerlo en un child theme para no perderlo con la próxima actualización.
add_action("send_headers", function () {
header("X-Frame-Options: SAMEORIGIN");
header("X-Content-Type-Options: nosniff");
});
Editás el .htaccess, lo subís por FTP, purgás la caché del CDN, probás en una ventana de incógnito, ves la cabecera nueva en curl, respirás tranquilo, y dos horas después un cliente te avisa que el calendario de reservas desapareció porque la CSP le bloqueó el dominio del proveedor que nadie tenía anotado en ningún lado. Por eso: un cambio por vez, y verificación después de cada uno.
¿Orden de carga? El servidor gana. Si Apache ya manda la cabecera, un plugin la va a duplicar o pisar. Elegí un solo lugar, y si usás Cloudflare o el CDN del hosting, purgá caché tras cada cambio; si no, vas a auditar headers viejos toda la tarde. En configurar el firewall de Sucuri profundizamos sobre esto.
¿Qué plugins sirven para gestionar cabeceras HTTP en WordPress?
Pocos plugins hacen bien esta tarea, y varios de los famosos ni la intentan. Mi criterio después de años dando soporte: si tenés acceso al servidor, manejá las cabeceras ahí y ahorráte un plugin; si no, buscá uno dedicado y verificá con curl después de activarlo.
| Opción | Tipo | Aporte en cabeceras | Ojo con |
|---|---|---|---|
| Edición directa (.htaccess / nginx.conf) | Servidor | Control total, cero peso extra | Necesitás acceso al hosting |
| Really Simple SSL (Pro) | Plugin | Módulo de cabeceras con presets | Las funciones finas son de pago |
| Plugins dedicados de HTTP Headers | Plugin | Interfaz por cabecera, gratuitos | Un plugin más que mantener y auditar |
| Sucuri (WAF cloud) | Servicio | Agrega cabeceras en el borde | Implica mover DNS hacia el firewall |
| Wordfence | Plugin de seguridad | Firewall y escáner potentes | La gestión fina de CSP no es su fuerte |
| WP Rocket | Caché | Rendimiento y caché | No es su terreno; buscá otro camino |
Según el tipo de sitio, mi recomendación cambia:
- Blog personal: .htaccess y listo; un plugin dedicado solo si tu hosting no te da acceso a archivos.
- Tienda WooCommerce: armá la CSP en Report-Only una semana, revisá la consola, y después activala en firme; las pasarelas suman dominios todo el tiempo.
- Publisher con muchos embeds: frame-ancestors amplio y auditoría mensual, porque cada socio de contenido nuevo es un origen nuevo.
Los botones de «blindar todo» que traen algunos packs de seguridad me generan desconfianza: aplican presets genéricos con unsafe-inline en todas las directivas, y eso es una falsa sensación de blindaje. Menos magia, más control.
¿Cómo verificar que tus cabeceras HTTP están activas?
Tres herramientas gratuitas cubren todo: securityheaders.com para el puntaje, curl para el dato crudo y DevTools para inspeccionar respuesta por respuesta. Entre las tres te sacás cualquier duda en cinco minutos.
- SecurityHeaders.com: escribís tu dominio y te da una nota de A+ a F con el detalle por cabecera. Fijate que el informe marca exactamente qué falta para subir de letra.
- curl -I https://tudominio.com: desde la terminal, te muestra los headers tal como salen del servidor. Sumale grep -i security para filtrar el ruido.
- DevTools (F12, pestaña Network): recargá, cliqueá el documento principal y mirá Response Headers. Ideal para ver qué llega después de pasar por el CDN.
- chrome://net-internals/#hsts: consultá si tu dominio ya tiene política HSTS cacheada en ese navegador. Poco conocido, muy útil cuando HSTS se vuelve contra vos.
Acordate que tu entorno local puede mostrar otras cabeceras que producción: el CDN o el WAF del medio agrega, quita o cachea cosas. Verificá siempre contra el dominio público. Cuando la CSP bloquea algo, la consola lo grita con mensajes «Refused to load… violates Content-Security-Policy», así que también la consola es una herramienta de verificación. Mozilla mantuvo por años su propio escáner (Observatory); si querés sumarlo a la rutina, chequeá primero que siga operativo.
¿Las cabeceras de seguridad afectan el SEO o la velocidad de WordPress?
No en la práctica. Un conjunto completo de cabeceras pesa unos cientos de bytes por respuesta, imperceptible frente a una sola imagen sin optimizar. Al revés: HTTPS es factor de ranking confirmado por Google hace años, y HSTS garantiza que nadie caiga en la versión insegura de tu sitio.
Lo único que puede lastimar tu SEO es una CSP mal armada que bloquee recursos: si el CSS principal no carga, la página se ve rota, el usuario rebota y ahí sí perdés posiciones. Por eso existe Report-Only, y por eso se prueba antes de activar. Cubrimos ese tema en detalle en activar la verificación en dos pasos.
Errores comunes al configurar cabeceras en WordPress (y cómo arreglarlos)
¿Por qué mi WordPress se rompe al activar Content-Security-Policy?
Síntoma típico: el sitio carga a medias, la consola acumula mensajes de violación de CSP y el carrusel no arranca. Casi siempre es un recurso externo que no anotaste en script-src o style-src. Solución: volvé a Report-Only, colectá las violaciones durante una semana, agregá esos orígenes y recién entonces activá la política en firme. Evitá el atajo de unsafe-inline global, que te deja abierta justo la puerta que querías cerrar.
¿Por qué mi sitio queda inaccesible después de activar HSTS?
Activaste HSTS con includeSubDomains y algún subdominio seguía en HTTP, o tu certificado no cubre todo. El navegador ahora exige HTTPS donde no lo hay, y el visitante ve error. Primero arreglá el certificado (uno wildcard cubre *.tudominio.com). El afectado puede limpiar la política local desde chrome://net-internals/#hsts, aunque eso solo vale para su navegador. Lección: max-age chico al principio, y subir de a poco.
¿Por qué securityheaders.com muestra cabeceras viejas que ya cambié?
Caché. El CDN guardó la respuesta anterior con sus headers y te la sigue sirviendo. Purgá la caché completa (no solo la de páginas) y volvé a probar. Si persiste, consultá el origen directamente, saltándote el CDN, para confirmar que el servidor ya manda lo nuevo. El problema casi nunca es tu configuración; es la capa de arriba.
¿Por qué un plugin pisa o duplica mis cabeceras?
Algunos plugins de seguridad envían sus propias cabeceras con prioridades distintas, y terminás con X-Frame-Options repetido o contradictorio. El resultado es impredecible según el navegador. Regla: un solo dueño por cabecera. Auditá con curl después de activar cada plugin nuevo y desactivá el que pelee con tu configuración de servidor.
Cabeceras HTTP en WordPress: qué está confirmado y qué depende de tu entorno
Lo confirmado, según la documentación oficial:
- La sintaxis y las directivas: están documentadas en MDN y en el proyecto Secure Headers de OWASP; no cambian según tu hosting.
- ALLOW-FROM está muerto: los navegadores lo retiraron; para permitir orígenes específicos, frame-ancestors.
- Preload exige compromiso: un año de max-age, includeSubDomains y HTTPS en todos los subdominios, según los requisitos públicos de la lista de Chromium.
Lo que depende de tu entorno:
- Si podés editar .htaccess o nginx.conf: la mayoría de los hostings con cPanel lo permite, pero algunos planes administrados lo restringen.
- Cómo trata las cabeceras tu CDN o WAF: puede agregar, quitar o cachear; hay que auditarlo caso por caso.
- Llegar a A+: depende de los servicios externos que cargues; con muchos terceros, una A zafa perfecto y es un resultado honesto.
Preguntas Frecuentes
¿Qué son las cabeceras HTTP de seguridad en WordPress?
Son instrucciones que el servidor incluye en cada respuesta HTTP para restringir el comportamiento del navegador: qué scripts puede cargar, si la página puede mostrarse en un iframe ajeno y si debe usar siempre HTTPS. En WordPress se configuran en el servidor (.htaccess, nginx.conf, wp-config.php) o con plugins dedicados, y las principales son CSP, HSTS y X-Frame-Options.
¿Cómo implemento CSP en WordPress sin romper el sitio?
Arrancá con Content-Security-Policy-Report-Only, que registra violaciones sin bloquear nada, y revisá la consola del navegador durante unos días. Con el inventario de dominios en mano, escribí la política definitiva con script-src, style-src y frame-src, y activala. Probá siempre en staging antes de producción.
¿Cómo activo HSTS en WordPress de forma segura?
Primero confirmá que todo el sitio y los subdominios funcionan con certificado válido. Después agregá la cabecera Strict-Transport-Security con un max-age corto (300 segundos), verificá que nada se rompa y subilo de a poco hasta 31536000. Recién cuando estés seguro, considerá includeSubDomains y preload, porque revertirlos toma meses.
¿Qué plugin uso para agregar cabeceras de seguridad en WordPress?
Si tu hosting te da acceso a archivos, ninguno: editá el .htaccess directamente, que es más rápido y tiene menos puntos de falla. Si necesitás interfaz gráfica, los plugins dedicados de cabeceras HTTP cumplen, y Really Simple SSL suma un módulo de headers en su versión Pro. No esperes esta función de plugins de caché o firewall genéricos.
¿Cómo verifico que mis cabeceras HTTP están activas?
Entrá a securityheaders.com, poné tu dominio y mirá la nota con el detalle por cabecera. Para el dato crudo, corré curl -I https://tudominio.com en la terminal, o abrí DevTools, sección Network, y revisá los Response Headers del documento principal.
Conclusión
Configurar las cabeceras HTTP de seguridad en WordPress dejó de ser opcional: es la diferencia entre un sitio que ejecuta cualquier script inyectado y uno que le dice al navegador exactamente qué aceptar. El camino es corto: CSP en modo Report-Only primero, HSTS con max-age progresivo después, X-Frame-Options o frame-ancestors para cerrar el clickjacking, y verificación en securityheaders.com al final. Una tarde de trabajo, cero costo. Si tu hosting te da acceso al .htaccess, empezá por ahí hoy; si preferís delegar, elegí un proveedor que te deje tocar la configuración del servidor, porque tarde o temprano la vas a necesitar.
Fuentes
- MDN Web Docs – Content-Security-Policy: referencia oficial de directivas y valores
- MDN Web Docs – Strict-Transport-Security: sintaxis de max-age, includeSubDomains y preload
- OWASP Secure Headers Project – guía de cabeceras de seguridad recomendadas
- SecurityHeaders.com – escáner gratuito que califica las cabeceras de tu dominio de A+ a F