Cabeceras de seguridad en WordPress contra XSS y CSRF

Cada vez que un navegador carga tu web, intercambia con el servidor una serie de cabeceras HTTP que casi nadie mira, pero que deciden cosas como si un script externo puede ejecutarse en tu página o si tu sitio puede cargarse dentro de un iframe ajeno. En un CMS tan extendido como WordPress, dejar esas cabeceras sin configurar es dejar la puerta entreabierta a dos de los ataques más comunes en la web: Cross-Site Scripting (XSS) y Cross-Site Request Forgery (CSRF).

Qué son XSS y CSRF, en la práctica

Un ataque XSS inyecta código JavaScript malicioso en tu sitio, normalmente a través de un campo de formulario o comentario mal saneado. Ese código se ejecuta en el navegador de quien visita la página y puede robar sesiones, redirigir a otro sitio o manipular lo que ve el usuario:

<script>alert('Tu sitio ha sido comprometido');</script>

CSRF funciona de forma distinta: explota la confianza que tu sitio tiene en la sesión ya iniciada de un usuario. Si ese usuario, con la sesión de WordPress abierta, visita una página maliciosa con una petición oculta como esta:

<img src="https://tuwordpress.com/wp-admin/admin.php?action=delete_user&id=1" />

el navegador envía esa petición con las cookies de sesión válidas, sin que el usuario se entere ni lo consienta.

Las cabeceras que cierran esas puertas

Todas estas funciones van en el functions.php del tema (o mejor, en un plugin propio) y se enganchan al hook send_headers.

X-Content-Type-Options

Impide que el navegador reinterprete el tipo de archivo por su cuenta, algo que en algunos casos permite colar código ejecutable donde se esperaba texto plano:

function agregar_cabeceras_seguridad() {
    header('X-Content-Type-Options: nosniff');
}
add_action('send_headers', 'agregar_cabeceras_seguridad');

X-Frame-Options

Evita que alguien cargue tu web dentro de un iframe en su propio dominio para engañar al usuario con un clic (clickjacking):

function agregar_x_frame_options() {
    header('X-Frame-Options: SAMEORIGIN');
}
add_action('send_headers', 'agregar_x_frame_options');

X-XSS-Protection

Los navegadores modernos ya no la necesitan porque han sustituido este filtro por mecanismos más robustos, pero si aún te llega tráfico de navegadores antiguos, sigue teniendo sentido activarla:

function habilitar_x_xss_protection() {
    header('X-XSS-Protection: 1; mode=block');
}
add_action('send_headers', 'habilitar_x_xss_protection');

Content Security Policy (CSP)

Es la cabecera con más impacto real contra XSS, porque le dice al navegador exactamente desde qué dominios puede cargar scripts, estilos o imágenes. Cuálquier cosa fuera de esa lista se bloquea, aunque haya conseguido inyectarse en el HTML:

function configurar_csp() {
    header("Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com;");
}
add_action('send_headers', 'configurar_csp');

Eso sí, en un WordPress con muchos plugins que cargan recursos de terceros conviene revisarla con calma, porque una política demasiado estricta rompe funcionalidades sin avisar.

Atributo SameSite en las cookies

Esta es la que ataca directamente el CSRF: le dice al navegador que no envíe la cookie de sesión cuando la petición viene de otro dominio, que es justo lo que necesita el ataque del ejemplo anterior para funcionar:

function configurar_samesite_cookie($cookies) {
    foreach ($cookies as $name => $value) {
        setcookie($name, $value, [
            'samesite' => 'Strict',
            'secure' => true,
            'httponly' => true
        ]);
    }
}
add_action('send_headers', 'configurar_samesite_cookie');

Cómo comprobar que las cabeceras están activas

Con la pestaña «Red» de las herramientas de desarrollo del navegador puedes inspeccionar la respuesta de cualquier petición y ver qué cabeceras llegan de verdad. Si prefieres un análisis más completo, Security Headers escanea tu dominio y puntúa cada cabecera de seguridad presente o ausente.

Estas cabeceras no sustituyen otras capas de seguridad como un buen sistema de autenticación con 2FA o las medidas básicas de hardening frente a hackers, pero cierran una vía de ataque que muchas instalaciones dejan completamente abierta. Y si tu preocupación va más allá del código malicioso clásico, proteger el CMS contra inyecciones de contenido y redirecciones que dañan el SEO aborda las amenazas más recientes que combinan hackeo y posicionamiento.

Preguntas frecuentes

¿Estas cabeceras funcionan solas o necesito un plugin?

Funcionan solas con el código PHP mostrado, pero también puedes configurarlas a nivel de servidor (Apache, Nginx) o con un plugin de seguridad si prefieres no tocar código. El resultado es el mismo, cambia solo dónde vive la configuración.

¿Puede una CSP mal configurada romper mi sitio?

Sí. Si bloqueas un dominio del que dependen tus plugins (un CDN, una fuente de Google Fonts, un script de analítica), esos recursos dejan de cargar sin ningún aviso visible para el usuario. Prueba siempre primero en modo report-only antes de aplicar la política en producción.

¿Es necesario X-XSS-Protection en 2026?

Chrome y Edge ya la ignoran porque confían en la CSP como mecanismo principal. Aún así, añadirla no hace daño y protege a la minoría de visitantes que sigue usando navegadores antiguos que sí la respetan.

¿SameSite Strict puede dar problemas con pasarelas de pago externas?

Sí, si el flujo de pago redirige a un dominio externo y vuelve, Strict puede bloquear la cookie de sesión. En esos casos, Lax suele ser un término medio que sigue frenando el CSRF sin romper esas integraciones.

Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.