Verificar la seguridad de su sitio en un minuto: las cabeceras HTTP que importan
Las cabeceras HTTP de su sitio revelan en segundos si las protecciones básicas están en su lugar. Explicación de cada cabecera, herramienta de verificación en línea y configuraciones listas para copiar para Nginx, Apache y Node.js.
Cada vez que se carga una página, su servidor envía al navegador una decena de líneas invisibles: las cabeceras HTTP. Algunas indican al navegador lo que tiene derecho a hacer con la página. Otras revelan sin querer qué tecnología funciona detrás, y en qué versión. Leer esas líneas lleva unos segundos y da una primera imagen del cuidado puesto en la configuración.
Este artículo explica lo que protege cada cabecera y después le propone una herramienta que consulta su sitio y le dice lo que falta. Está al final de esta página, y en su página dedicada.
Lo que una cabecera puede impedir, y lo que no
Tomemos un caso corriente: un campo de comentarios mal filtrado deja pasar un fragmento de JavaScript, o una biblioteca cargada desde un CDN se sustituye por una versión trucada. Sin protección, el navegador ejecuta ese código como si viniera de usted. Con una política de seguridad de contenido correctamente escrita, rechaza cualquier script que no proceda de una fuente que usted haya listado. El atacante debe entonces comprometer un dominio concreto, y no colar código en cualquier parte.
Ese es el principio de todas las cabeceras de seguridad. No corrigen una falla en su código. Limitan lo que un atacante puede hacer con ella.
También tienen un límite, y las tiendas Shopify secuestradas en octubre de 2026 lo ilustran bien. El código malicioso lo servía el editor de una aplicación legítima, es decir, un dominio que el comerciante habría autorizado de todos modos. Una política de seguridad no habría bloqueado nada. Cuando el peligro viene de una extensión de confianza, la única defensa es limitar el número de extensiones y vigilarlas.
Las cabeceras revisadas
HTTPS y Strict-Transport-Security
El HTTPS cifra los intercambios. Pero un visitante que escribe su dirección sin el prefijo llega primero en HTTP, y es en ese momento cuando un ataque en una red pública puede interceptarlo. La cabecera HSTS pide al navegador que deje de intentar el HTTP para su dominio, durante el tiempo indicado. Solo protege a partir de la segunda visita: el navegador debe haber visto la cabecera una primera vez para recordarla. Para cubrir también la primera visita, hay que inscribir el dominio en la lista de precarga de los navegadores, con la directiva preload. Seis meses es el mínimo útil, un año es el valor habitual.
Content-Security-Policy
Es la cabecera más potente, y la más delicada de escribir. Enumera las fuentes autorizadas para los scripts, los estilos, las imágenes, las fuentes tipográficas y las conexiones. Todo lo que no figura en ella se bloquea. Una política que autoriza * para los scripts no aporta nada. Una política demasiado estricta rompe el sitio. El método correcto: empezar en modo solo informe, leer las violaciones que remiten los navegadores y después pasar al modo bloqueante.
X-Frame-Options y frame-ancestors
La cabecera X-Frame-Options y la directiva frame-ancestors de la CSP impiden que una página de su sitio se muestre en un marco invisible en un sitio de terceros. La trampa clásica: un botón atractivo superpuesto a su botón “Confirmar”, para hacer que el visitante haga clic sin saberlo. La directiva sustituye progresivamente a la cabecera, pero ambas coexisten sin conflicto.
Referrer-Policy
Cuando un visitante hace clic en un enlace externo desde su sitio, el navegador transmite la dirección de la página de origen. Con una política permisiva como unsafe-url, un sitio de terceros ve la dirección completa, parámetros incluidos. El valor strict-origin-when-cross-origin solo transmite el origen, es decir, el protocolo, el dominio y el puerto. Es además el valor por defecto de los navegadores recientes: la ausencia de la cabecera no expone a sus visitantes. Añadirla hace explícita esa elección y cubre los navegadores antiguos.
Permissions-Policy
Esta cabecera desactiva los accesos que su sitio no utiliza: cámara, micrófono, geolocalización. Es opcional, pero cierra una puerta que un script inyectado podría abrir.
Los atributos de las cookies
Una cookie marcada Secure solo circula por HTTPS. Una cookie marcada HttpOnly es invisible para el JavaScript de la página, y por tanto para un script inyectado. El atributo SameSite, con el valor Lax o Strict, impide que se envíe desde un sitio de terceros, lo que corta las peticiones falsificadas. Una cookie de sesión sin estos tres atributos es el primer objetivo de un ataque por inyección.
Las versiones expuestas
Las cabeceras Server y X-Powered-By anuncian a veces la versión exacta del servidor o del lenguaje: nginx/1.24.0, PHP/8.3.20. Esta información no sirve de nada a sus visitantes. Para un atacante, indica directamente qué fallas probar. Desde los parches del 21 de octubre de 2026, un sitio que anuncia una versión de PHP inferior a 8.2.35, 8.3.36, 8.4.27 u 8.5.12 señala públicamente que es vulnerable a php2shell, una falla explotada en condiciones reales. Lo mismo ocurre con Node.js y Node2Shell: las versiones corregidas son 22.23.4, 24.22.1 y 26.12.1. La herramienta de abajo compara la versión anunciada con esos umbrales.
Cómo corregirlo
Las cabeceras se configuran en un único lugar, según su servidor. Cada bloque de abajo es directamente utilizable; adapte la CSP a los recursos externos que su sitio carga realmente.
Nginx, en el bloque server. Cuidado con la trampa más habitual: en cuanto un bloque location contiene su propia directiva add_header, deja de heredar las del bloque server. En ese caso, repita las cabeceras de seguridad en ese bloque, o agrúpelas en un archivo incluido en ambos niveles.
# Fuerza el HTTPS durante un año, subdominios incluidos
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Scripts y estilos limitados al propio dominio; adaptar según sus servicios externos
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'self'" 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;
# No anunciar la versión de Nginx
server_tokens off;
Apache, en el archivo .htaccess o en la configuración del sitio, con el módulo headers activado:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'self'"
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=()"
# Elimina la cabecera X-Powered-By añadida por PHP
Header unset X-Powered-By
Para ocultar la versión de Apache, la directiva ServerTokens Prod va en la configuración principal del servidor (httpd.conf o apache2.conf), nunca en un .htaccess, donde provoca un error 500.
PHP, para ocultar la versión sea cual sea el servidor, en php.ini:
; Elimina la cabecera X-Powered-By: PHP/x.y.z
expose_php = Off
Node.js con Express, la biblioteca helmet lo configura todo en una sola llamada. No gestiona Permissions-Policy, que se añade a mano para obtener la misma cobertura que las configuraciones de Nginx y Apache de arriba:
import helmet from 'helmet';
// Establece HSTS, CSP, nosniff, frame-ancestors, Referrer-Policy y elimina X-Powered-By
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
},
},
}));
// Permissions-Policy no está cubierto por helmet
app.use((request, response, next) => {
response.setHeader('Permissions-Policy', 'camera=(), microphone=(), geolocation=()');
next();
});
Shopify: usted no controla las cabeceras, Shopify las gestiona por usted. Su palanca está en otro sitio: el número de aplicaciones instaladas y la prueba regular de su proceso de pago en navegación privada.
Lo que la herramienta no ve
La verificación de abajo lee únicamente las cabeceras públicas de su página de inicio, una sola vez. No prueba su código, sus formularios, sus extensiones ni su base de datos. Un sitio puede obtener todos los puntos en verde y seguir siendo vulnerable por una extensión de WordPress obsoleta. A la inversa, un sitio con varios puntos naranjas no está necesariamente pirateado: simplemente le faltan salvaguardas.
Tome el resultado por lo que es: un primer diagnóstico. Queda por verificar las versiones que su servidor no anuncia, y que la herramienta por tanto no puede leer, y, para un sitio que cobra pagos o almacena datos de clientes, encargar una auditoría completa. Si el resultado le preocupa, o si no sabe quién se ocupa de estos ajustes en su sitio, escríbame.
Herramienta
¿Está su sitio correctamente configurado?
Introduzca la dirección de su sitio. El servidor lo consulta una vez, lee sus cabeceras HTTP y le indica lo que falta. No se guarda nada.
Resultado para
Tecnologías detectadas
Tienda Shopify: el servidor lo gestiona Shopify y las cabeceras son suyas. El riesgo real viene de las aplicaciones instaladas. Pruebe su proceso de pago en una ventana privada y compruebe que permanece en su dominio o en shopify.com.
Corregir primero
Nada urgente. Todos los puntos de abajo son correctos o informativos.
El detalle por tema
Esta verificación solo lee las cabeceras públicas de la página de inicio. No sustituye a una auditoría: un sitio puede superar todos estos puntos y seguir siendo vulnerable en su código o extensiones.
¿Un punto rojo o varios naranjas? Hablemos