Si tienes una web WordPress debes ser estricto con la seguridad de tu sitio. Para dirigir con éxito un blog, un negocio o una tienda online, debes asegurarte de que tu sitio sea totalmente seguro.
Los clientes visitan tu web, compran productos y pasan información sensible como contraseñas, datos de tarjetas de crédito, etc. Si hay un lugar donde infiltrarse en tu web, entonces los hackers pueden robar los datos de tus clientes.
Cuando se trata de la seguridad de una web, hay muchas cosas que puedes hacer para reforzar la seguridad de WordPress.
Un buen lugar para mejorar la seguridad de su sitio web es añadir cabeceras de seguridad HTTP en tu web WordPress para asegurarte de que te mantienes al día con las mejores prácticas de seguridad.
Las cabeceras de seguridad de HTTP añaden otra capa de seguridad ayudando a reducir los ataques y las vulnerabilidades de seguridad.
En este artículo, veremos qué son las cabeceras de respuesta HTTP y cómo añadir cabeceras de seguridad HTTP en WordPress.
¿Qué son las cabeceras de seguridad HTTP?

Cuando un usuario visita una web a través de un navegador, el servidor reacciona con cabeceras de respuesta HTTP. Estas cabeceras informan al navegador web cómo actuar durante su interacción con el sitio web.
Estas cabeceras generalmente consisten en metadatos como el control de la caché, códigos de error de estado, cifrado de contenidos, etc.
Al utilizar las cabeceras de respuesta de HTTP, puedes reforzar la seguridad de tu web y también evitar/mitigar los ataques.
Por ejemplo, al añadir la seguridad de transporte estricta, puedes forzar a los últimos navegadores web como Google Chrome, Firefox y Safari a que se comuniquen con tu sitio web sólo a través de HTTPS.
Echemos un vistazo a las 6 cabeceras de seguridad HTTP que veremos:
- HTTP Strict Transport Security (HSTS)
- X-Frame-Options
- X-XSS-Protection
- X-Content-Type-Options
- Referrer-Policy
- Feature-Policy
- Content-Security-Policy (CSP)
HTTP Strict Transport Security (HSTS)
Digamos que tienes un sitio ejemplo.com, y configuras un certificado SSL/TLS para pasar de HTTP a HTTPS.
Ahora sabes que tu web es accesible sólo con HTTPS.
¿Y si te digo que tu web sigue siendo accesible a través de HTTP? Sí, lo has oído bien. Hay varios scripts disponibles que los hackers utilizan para acceder a una web a través de HTTP.
Utilizando la seguridad de transporte estricta (HSTS), puedes forzar a los últimos navegadores web como Google Chrome, Firefox y Safari para que se comuniquen con tu web sólo a través de HTTPS. Así que si un atacante intenta abrir tu sitio WordPress a través de HTTP, el navegador web no cargará la página.
Parámetros
max-age– configurará el tiempo, en segundos, en los que el navegador recordará que este sitio solo es accesible usando HTTPSincludeSubDomains– es un parámetro adicional que puede usarse para aplicar esta regla también a todos los subdominios del sitio
X-XSS Protection
X-XSS, también conocido como cross-site scripting, es una cabecera de seguridad que protege los sitios contra el cross-site scripting.
Por defecto, esta cabecera de seguridad está integrada y activa en los navegadores web modernos. Al implementarlo, el navegador se verá obligado a cargarla. Esta cabecera de seguridad no dejará que se cargue una página si detecta un ataque de cross-site scripting.
Parámetros
0– desactiva el filtro1activa el filtro1; mode=blockactiva el filtro con el parámetro1y además bloquea que la web se cargue conmode=block1; report=https://url-de-tu-informe/activa el filtro con el parámetro1y luego sanea la petición y envía el informe a la url definida con el parámetroreport=
X-Content-Type-Options
El X-Content-Type-Options es una especie de cabecera de seguridad que evita que Google Chrome, Internet Explorer y Firefox hagan MIME-Sniffing a una respuesta distinta del tipo de contenido declarado.
Esta cabecera de seguridad protege el contenido y reduce el riesgo de descargas no autorizadas.
Tiene montones de opciones de configuración y parámetros posibles pero el parámetro más común es nosniff.
X-Frame Options
La cabecera x-frame-options protege las webs contra el robo de clics al no permitir que rellenen los iframes en tu web. Es compatible con IE 8+, Chrome 4.1+, Firefox 3.6.9+, Opera 10.5+ y Safari 4+.
En este método, un atacante engaña al usuario para que haga clic en algo que no está ahí. Un usuario puede creer que está en el sitio principal; sin embargo, hay otra cosa ejecutándose de fondo. De esta manera, los hackers pueden robar información de tu navegador web.
Parámetros
deny– denegará completamente la visualización del iframe.sameorigin– denegará si el origen no coincide con el sitio.allow-from: DOMAIN– este parámetro permite la visualización del iframe si se carga de un dominio específico
Content-Security-Policy (CSP)
La política de seguridad de contenido ayuda a reducir el riesgo de ataques XSS en los navegadores modernos, declarando qué recursos dinámicos tienen permiso para cargarse y de dónde.
Al igual que con X-Content-Type-Options, la cabecera Content-Security-Policy tiene un montón de opciones de configuración y de parámetros potenciales, así que mencionaré los más recomendables y utilizados.
Parámetros
default-src– es la política por defecto para cargar contenido como JavaScript, imágenes, CSS, fuentes, peticiones AJAX, Frames, medios en HTML5script-src– define los orígenes válidos para cargar JavaScriptconnect-src– se aplica a XMLHttpRequest (AJAX), WebSocket o EventSource. Si no está permitido el navegador emula un código de estado HTTP 400img-src– define los orígenes válidos para cargar imágenesstyle-src– define los orígenes válidos para cargar hojas de estilos
Referrer-Policy
Cuando un usuario visita una web, inmediatamente se incluye una cabecera «Referrer» que informa al servidor de dónde procede el visitante. Esta cabecera se utiliza con fines estadísticos.
Como comprenderás, esto presenta un problema de privacidad personal. Esto puede evitarse añadiendo la referrer-policy a tu sitio WordPress.
Feature-Policy
La feature-policy es una especie de cabecera de seguridad que permite a los propietarios de la web permitir y denegar determinadas funciones de la plataforma web en sus propias páginas y en las que ellos incrustan.
Utilizando la cabecera feature-policy, como propietario de un sitio puedes restringir características del navegador.
Para cada una de las características, debes especificar lo que está permitido y lo que no. Estas son las posibilidades:
- geolocation
- midi
- notifications
- push
- sync-xhr
- microphone
- camera
- magnetometer
- gyroscope
- speaker
- vibrate
- fullscreen
- payment
Por ejemplo, si quieres desactivar la geolocalización y la cámara en tu sitio WordPress, tienes que definir una feature-policy así:
Feature-Policy: geolocation ‘none’ ; camera ‘none’
Al especificar el parámetro ‘none’ en la lista de orígenes se desactivará esta funcionalidad.
Cómo añadir cabeceras de respuesta HTTP en WordPress
Puedes añadir las cabeceras de seguridad HTTP a tu sitio WordPress de varias maneras. Puedes editar el archivo .htaccess en un servidor Apache o el archivo nginx.conf en NGINX, puedes crear una función, o puedes usar plugins.
Notas importantes:
- Antes de añadir cabeceras de seguridad HTTP a tu sitio WordPress asegúrate de que tengas instalado y activo un certificado SSL, o en caso contrario tu sitio dejará de ser accesible.
- Antes de editar cualquier archivo asegúrate de hacer una copia de seguridad.
Cómo generar cabeceras de seguridad HTTP de manera segura para WordPress
Antes de decidirte por qué método usar para añadir las security headers HTTP a tu web WordPress, y en general, te recomiendo que las crees desde la herramienta online que he creado, totalmente gratis, en el generador de cabeceras de seguridad HTTP para WordPress.
Puedes probar varias configuraciones, preajustes para distintos tipos de web, información detallada sobre qué hace cada cabecera, ejemplos, y muchas cabeceras adicionales a las que hemos visto, totalmente actualizadas, y lo mejor es que puedes generar el código necesario tanto para .htaccess y nginx.conf como para una función PHP, e incluso descargarlo.
Cómo añadir cabeceras de seguridad HTTP en WordPress al archivo .htaccess
Si tu servidor es Apache entonces debes añadir al final de este archivo unas cabeceras como las de este ejemplo, aplicando los parámetros que hemos visto anteriormente que quieras incorporar en tu sitio:
# BEGIN CABECERAS DE SEGURIDAD (AyudaWP 2025)
Options -Indexes
ServerSignature Off
Header set X-Content-Type-Options nosniff
Header always append X-Frame-Options SAMEORIGIN
Header set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security max-age=31536000
Header set Referrer-Policy: no-referrer-when-downgrade
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self' https:; media-src 'self' https:; frame-src 'self' https:; worker-src 'self' blob: https:; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';"
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
# END CABECERAS DE SEGURIDAD
Nota: estas cabeceras son las que tengo yo activas en el blog y consigues una puntuación de A+ en seguridad en las cabeceras HTTP, con total compatibilidad con WordPress, Woocommerce y maquetadores.
Si lo prefieres, puedes añadir estas cabeceras desde una función que puedes cargar añadiéndola al final de archivo functions.php del tema activo o de tu plugin de utilidades, así:
/**
* Añadir cabeceras HTTP de seguridad a WordPress
*/
function ayudawp_add_security_headers() {
// Solo añadimos cabeceras si no se han enviado ya
if (!headers_sent()) {
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: SAMEORIGIN');
header('X-XSS-Protection: 1; mode=block');
header('Strict-Transport-Security: max-age=31536000');
header('Referrer-Policy: no-referrer-when-downgrade');
header('Content-Security-Policy: default-src \'self\'; script-src \'self\' \'unsafe-inline\' \'unsafe-eval\' https:; style-src \'self\' \'unsafe-inline\' https:; img-src \'self\' data: https:; font-src \'self\' data: https:; connect-src \'self\' https:; media-src \'self\' https:; frame-src \'self\' https:; worker-src \'self\' blob: https:; object-src \'none\'; frame-ancestors \'self\'; base-uri \'self\'; form-action \'self\';');
header('Permissions-Policy: geolocation=(), microphone=(), camera=()');
}
}
// Añadir cabeceras a web visible y admin
add_action('init', 'ayudawp_add_security_headers');
Notas importantes sobre el método de función WordPress
Las cabeceras HTTP que estamos añadiendo (como X-Content-Type-Options, X-Frame-Options, etc.) se pueden enviar desde PHP usando la función header(), pero hay que tener en cuenta que:
- Solo funcionan para contenido servido por WordPress (páginas, entradas, admin, etc.)
- No protegen archivos estáticos como CSS, JS, imágenes, etc.
- Se pueden sobrescribir si el servidor web tiene configuraciones conflictivas
Además, la función debe mantenerse siempre activa, en el functions.php del tema o plugin de snippets, porque:
- Las cabeceras HTTP se envían con cada petición
- Si quitas la función, las cabeceras dejan de enviarse inmediatamente
- No se guardan en ningún sitio, son dinámicas
Resumiendo:
- Salvo que no puedas o sepas, SIEMPRE es mejor añadirlas directamente al archivo
.htaccesscomo en el primer ejemplo, y no mediante una función WordPress.
Cómo añadir cabeceras de seguridad HTTP en WordPress al archivo nginx.conf
Si tu servidor es NGINX entonces deberás añadir las cabeceras de seguridad HTTP al archivo de configuración nginx.conf, como en este ejemplo:
# En el bloque server server_tokens off; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN; add_header X-XSS-Protection "1; mode=block"; add_header Strict-Transport-Security "max-age=31536000"; add_header Referrer-Policy no-referrer-when-downgrade; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; media-src 'self'; object-src 'none'; child-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';"; add_header Permissions-Policy "geolocation=(), microphone=(), camera=()";
Cómo añadir cabeceras de seguridad HTTP en WordPress con plugins

Pues sí, también hay plugins para WordPress que permiten añadir las cabeceras de seguridad HTTP en WordPress. Estos son algunos de los disponibles de manera gratuita:
- HTTP Headers – Plugin muy completo y fácil de utilizar si tienes un conocimiento básico de los posibles parámetros de las distintas cabeceras de seguridad. Además de cabeceras de seguridad permite añadir otras de control de acceso, caché, compresión, etc. Muy muy completo.
- Redirection – Este fantástico plugin de redirecciones también tiene una herramienta con la que añadir las cabeceras de seguridad a tu sitio web.
- SG Security – Ya iba siendo hora que un plugin de seguridad tuviese la funcionalidad de añadir cabeceras de seguridad, y el de SiteGround añade las principales a golpe de clic.
- HTTP headers to improve website security – Algo más complejo de configurar que el anterior pero igual de efectivo.
- GD Security Headers – Otro estupendo plugins con el que configurar los parámetros y añadir las distintas cabeceras de seguridad HTTP.
Si quieres que te recomiende uno de ellos no sabría decirte porque los tres funcionan perfectamente y lo único que les diferencia es la interfaz, así que instálalos y usa el que te parezca más intuitivo a la hora de configurar los distintos parámetros.
Comprobar las cabeceras de seguridad HTTP
Una vez que hayas añadido cabeceras de seguridad HTTP no está de más comprobar que estas están funcionando correctamente.
Un sitio estupendo para comprobarlo rápidamente es la web securityheaders.com. Solo tienes que poner la URL de tu sitio, y te mostrará de inmediato si tienes cabeceras de seguridad HTTP y cuáles.
¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!









Buenas Fer. Me da error tanto en plugin como en .htaccess.
Prueba a ver ahora con el functions, sino prueba con el primer plugin, las añade de manera muy limpia
Hola Alonso, si esta opción es tan buena. ¿porque la mayoría de los websites no la usan?Un ejemplo es tu propio website, Ayuda WordPress también no usa las cabeceras. Yo intenté hace un tiempo atrás agregar las cabeceras al archivo httacess y al Functions si exito. Yo uso un montón de plugins y ademas AdSense. ¿Dará algún tipo de conflicto con los ingresos? ¿Afecta las impresiones de e página? Aguardo tus respuestas y muchas gracias por el posts, no hay algo parecido en español.
Yo no las utilizo aquí porque hago muchos cambios para probar cosas, utilizo muchos recursos externos y no quiero andar añadiéndolas y quitándolas.
Hay gente que no las usa porque…
1. No es fácil comprender a primer golpe de vista para lo que sirve cada una, y por eso he tratado de explicar las más importantes.
2. A veces el mal uso o aplicación de los parámetros impide el funcionamiento «normal» de la web, por falta de comprensión de los mismos.
3. Algunos, como HST, no se usaban porque el uso de HTTPS era muy pequeño y no siempre permanente, actualmente lo raro empieza a ser ver webs sin SSL
Fernando, disculpa que te cambie el nombre. Estaba desde el celular respondiendo al otro muchacho y se copió el nombre Alonso.
En fin yo estoy igual que tú, no he las implemento por las mismas razones. Aunque son importantes, ahora son una señal de puntuación para el algoritmo de Google. También puedes ver tu puntuación de seguridad desde aquí: http://www.webpagetest.org/
Espero que se implemente mejor el código, hace unos meses me pase 1 día entero y no pude hacerlo funcionar por que me arrojaba error. Debe ser por que tengo 21 plug-ins corriendo en el website.
Muchas gracias por los conceptos y definiciones están bárbaros.
La cantidad de plugins no es relevante, sino cuán bueno sea el código
Muy, pero muy agradecido, me voy a poner a trabajar hoy mismo.
Estuve usando el site https://securityheaders.com/, es increíble la cantidad de sites muy conocidos que dan D, E o F.
Gracias!
cierto uno es Amazon.es
Hola, yo lo he añadido al final de functions.php y también me da error.
Prueba a ver ahora, he cambiado unas cosillas
por cierto, este es el error:
syntax error, unexpected ‘env’ (T_STRING), expecting ‘)’
Ahora si va, gracias!!
Lo siento, pensé que ya funcionaba pero sigue sin funcionar.
Buenas Fer.
Hay dos cabeceras que dan problemas:
Si la pones con el env=HTTPS no hace nada malo, pero al pasarlo por securityheaders.com te reporta que el formato del max-age es incorrecto
La otra es:
A mi directamente me da un error 500. La tengo comentada hasta que la revise.
El resto funcionan bien, pero la de Content-Security-Policy es la más delicada, ya que dependiendo de como tengas la Web puede cargarte unas cosas sí y otras no. Es digamos, la más «jodida» de configurar.
Seguimos!!!
Feliz Tuesday.
Gracias… Puesto que la información es demasiado técnica para mi entendimiento, me he limitado a copiar y pegar el código que compartes en .htaccess con el siguiente resultado:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.
Gracias de nuevo…
Hola José.
Ese error te da por esta línea.
Prueba a cargar el resto, verás como no te da error.
Como comento en mi respuesta anterior, la cabecera de Content-Security-Policy es la más puñetera, si puedes vivir sin ella un tiempo, simplemente no la pongas o ponla pero comentada.
Seguimos!!!
Feliz miércoles.
Gracias Carlos… Me sigue dando error, por lo que he probado a quitar también la anterior: «Header Referrer-Policy: no-referrer-when-downgrade» y ya no da error….
Y bueno… si hasta ahora he sobrevivido, creo que podré vivir un tiempo más sin esas cabeceras 🙂
Gracias de nuevo… Abrazo…
Hola josé. Así es como lo tengo yo (He optado por ponerlas en mi plugin de funcionalidades)
// Agregar cabeceras de seguridad function cmdh_agregar_cabeceras_seguridad() { header( 'X-Content-Type-Options: nosniff' ); header( 'X-Frame-Options: SAMEORIGIN' ); header( 'X-XSS-Protection: 1;mode=block' ); header( 'Strict-Transport-Security: max-age=31536000' ); // He quitado la opción «env=HTTPS» ya que securityheaders.com daba un aviso diciendo que max.age tenía un valor inesperado o incorrecto // header( 'Content-Security-Policy: script-src https://miweb.com' ); // Antes de activar, definir qué dominios externos cargan Scripts (p.e. GTM; GA; Cookiebot...) header( 'Referrer-Policy: no-referrer-when-downgrade' ); } add_action( 'send_headers', 'cmdh_agregar_cabeceras_seguridad' );Gracias Carlos… También yo tengo un plugin de funcionalidades… ¿Es suficiente con copiar y pegar ese código? Así lo he hecho, y no me da ningún error… incluso con
header( 'Content-Security-Policy: script-src https://miweb.com' );/ sin comentar… Dices que «Antes de activar, definir qué dominios externos cargan Scripts (p.e. GTM; GA; Cookiebot…)» ¿Dónde y cómo defino eso? Aunque tampoco sé qué dominios externos cargan scripts… pero diría que ninguno…Gracias de nuevo… Abrazo…
Hola José.
A ver la línea que tengo comentada es por que tengo que definir qué webs cargan scripts, css y otros recursos. En principio tal y como está si la pones sin comentar es muy probable que no rompa nada «visible», pero no es correcto, ya que si, por ejemplo, tienes Analytics o Tag Manager, al no autorizarlo mediante esa cabecera, no se cargarán los scripts, por eso la tengo comentada a falta de revisar la Web y añadir bien los parámetros de esa línea. Por ahora te recomiendo que la dejes comentada.
En cuanto a tu pregunta de ¿Dónde y cómo defino esto? Espero poder hacerlo y probarlo para poderte dar respuesta.
Feliz viernes.
Gracias Carlos… No tengo Analytics ni Tag Manager, y como dije, creo que ningún dominio externo carga scripts… aunque utilizo el sistema de comentarios Disqus… pero no se ha roto al añadir el código… ¿En caso de que ningún dominio externo cargue scripts, lo dejo así o elimino esa línea?
Gracias de nuevo… Feliz Finde… Y Comienzode…
he utilizado estas para servidor OpenLiteSpeed y obtengo una A+ :
function set_http_security_headers() {
header( ‘Content-Security-Policy: default-src \’self\» );
header( ‘X-Content-Type-Options: nosniff’ );
header( ‘X-Frame-Options: SAMEORIGIN’ );
header( ‘X-XSS-Protection: 1; mode=block’ );
header( ‘Strict-Transport-Security: max-age=31536000; includeSubDomains; preload’ );
header( ‘Referrer-Policy: strict-origin-when-cross-origin’ );
header( ‘Permissions-Policy: geolocation=(), microphone=(), camera=()’ );
}
add_action( ‘send_headers’, ‘set_http_security_headers’ );
Mientras no te dé problemas con tu contenido perfecto 🙂
Usando «Security Optimizer» de Siteground la herramienta «https://securityheaders.com» que mencionas me informa que faltan 5 cabeceras. No encuentro ninguna configuración o ajuste al respecto en los poquititos ajustes del plugin.. ¡¡¡ FELIZ 2024 !!!
Actualmente solo añade una cabecera de seguridad, antes añadía más pero lo quitaron porque a algunos sitios no les iba bien. Toca añadirlas manualmente como explico aquí: Cómo añadir cabeceras de seguridad HTTP en WordPress
Hola Fernando, gracias por este material…
Después de leer este post varias veces, tengo mis dudas, bastantes.
Yo tenia unas cabeceras que parecen correctas, estan desde hace tiempo y no se como las configure, pero me entraron dudas.
Es muy atrevido decir que las eches un vistazo, pero si tienes 5 minutos…, estaria bueno saber tu opinión
Gracias
Header set Strict-Transport-Security «max-age=31536000; includeSubDomains; preload»
Header always append X-Frame-Options SAMEORIGIN
Header always append X-XSS-Protection «1; mode=block»
Header always append X-Content-Type-Options «nosniff»
Header always append Referrer-Policy «no-referrer-when-downgrade»
Header always append Feature-Policy «geolocation ‘none’;midi ‘none’;notifications ‘none’;push ‘none’;sync-xhr ‘none’;microphone ‘none’;camera ‘none’;magnetometer ‘none’;gyroscope ‘none’;speaker ‘none’;vibrate ‘none’;fullscreen ‘self’;payment ‘none'»
Header always append Content-Security-Policy «default-src ‘self’; script-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’ https://ajax.googleapis.com https://maxcdn.bootstrapcdn.com https://cdnjs.cloudflare.com https://fonts.googleapis.com; style-src ‘self’ ‘unsafe-inline’ https://maxcdn.bootstrapcdn.com https://cdnjs.cloudflare.com https://fonts.googleapis.com; img-src ‘self’ data: https://www.gravatar.com https://ajax.googleapis.com https://maxcdn.bootstrapcdn.com https://cdnjs.cloudflare.com; font-src ‘self’ data: https://maxcdn.bootstrapcdn.com https://cdnjs.cloudflare.com https://fonts.gstatic.com; connect-src ‘self’; media-src ‘self’; object-src ‘self’; frame-ancestors ‘self’; form-action ‘self’; upgrade-insecure-requests»
Muy buenas, Fernando!!!
Este post tuyo ya tiene su tiempo, pero me ha tocado añadir cabeceras en una web de un cliente y aquí estoy a vueltas.
Las que tú recomiendas me funcionan todas. Solo la de Content-Security-Policy me muestra un warning (aunque sale en verde en el análisis):
«This policy contains ‘unsafe-inline’ which is dangerous in the script-src directive.
¿Cómo se puede corregir esto? He leído en otra web que es mejor sustituir ‘unsafe-inline’ por ‘unsafe-hashes’.
Yo no tengo ni papa de esto, por eso te pregunto.
Mil gracias!!!
Buena pregunta Edu. Te explico el tema porque hay bastante confusión al respecto:
Por qué aparece el warning
El warning es legítimo.
'unsafe-inline'en script-src básicamente dice «permite ejecutar cualquier JavaScript que esté inline en el HTML». Esto anula gran parte de la protección contra XSS que ofrece CSP, porque si un atacante consigue inyectar código en tu página, se ejecutará igualmente.¿Es mejor
'unsafe-hashes'?No, no es un sustituto directo. Son cosas diferentes:
'unsafe-inline': Permite TODO el JavaScript inline (cualquier<script>...</script>o atributos comoonclick="...")'unsafe-hashes': Solo permite event handlers inline (onclick, onload, etc.) cuyo hash hayas especificado explícitamente en la política. No afecta a bloques<script>.Si sustituyes uno por otro directamente, romperás la web.
Las alternativas reales (de más a menos segura)
El problema con WordPress
Aquí viene la cruda realidad: WordPress, sus temas y plugins generan scripts inline constantemente. El propio core lo hace. Gutenberg lo hace. WooCommerce lo hace. Prácticamente todos los plugins lo hacen.
Implementar una CSP sin
'unsafe-inline'en WordPress requiere:Mi consejo
Para un sitio WordPress típico, tu configuración actual es un buen equilibrio entre seguridad y funcionalidad. Tienes:
El warning del checker es correcto técnicamente, pero quitarlo en WordPress sin romper nada es complejo. Si quieres intentarlo, existe el plugin WP Content Security Policy que gestiona nonces, aunque requiere bastante configuración.