Cabeceras de seguridad HTTP: HSTS, CSP y más
Qué hacen HSTS, CSP, X-Frame-Options, Referrer-Policy y Permissions-Policy, qué valores usar y por qué una cabecera marcada para revisar no siempre es un fallo.
Comprobar las cabeceras de seguridad de una web
Qué son las cabeceras de seguridad
Toda respuesta HTTP empieza con cabeceras: pares de nombre y valor como Content-Type: text/html. Unas pocas cambian la forma en que el navegador trata la página. Enviarlas no cuesta nada, se aplican a todos los visitantes y se configuran en el servidor, en la plataforma de alojamiento o en una red de distribución de contenido, no en el HTML de la página.
IPNixa define sus propias cabeceras en un archivo _headers que Cloudflare sirve con cada página. El comprobador de este sitio solicita desde nuestro servidor la dirección que introduces, sigue hasta tres redirecciones y lee las cabeceras de la respuesta final.
Las seis cabeceras más importantes
Estas son las cabeceras que evalúa el comprobador. Los valores indicados son puntos de partida habituales y seguros; ajústalos a lo que necesite tu sitio.
| Cabecera | Qué evita | Valor habitual |
|---|---|---|
| Strict-Transport-Security (HSTS) | Que las conexiones se degraden a HTTP sin cifrar después de la primera visita | max-age=31536000; includeSubDomains |
| Content-Security-Policy (CSP) | Que se ejecuten scripts inyectados, lo que limita el cross-site scripting (XSS) | default-src 'self'; script-src 'self'; frame-ancestors 'none' |
| X-Frame-Options o frame-ancestors de CSP | Que otros sitios carguen la página en un marco oculto (clickjacking) | DENY, o frame-ancestors 'none' |
| X-Content-Type-Options | Que el navegador adivine el tipo de archivo y ejecute datos como script | nosniff |
| Referrer-Policy | Que las direcciones completas de las páginas, con rutas y parámetros de consulta, se filtren a otros sitios | strict-origin-when-cross-origin |
| Permissions-Policy | Que la página o sus marcos incrustados usen la cámara, el micrófono o la ubicación | camera=(), microphone=(), geolocation=() |
Cómo evalúa el comprobador de IPNixa cada cabecera
Cada cabecera recibe uno de tres estados: Presente, Revisar o No proporcionado. Revisar significa que la cabecera existe, pero su valor no cumple la regla indicada abajo; es una invitación a mirarla con más detalle, no una puntuación de seguridad.
- HSTS figura como Presente cuando aparece una sola vez con un max-age de al menos 15552000 segundos (180 días). Un max-age más corto o igual a cero se marca para revisar.
- CSP figura como Presente cuando controla los scripts mediante script-src o default-src y no contiene 'unsafe-inline', 'unsafe-eval' ni un * aislado en ninguna parte de la política. Una política Report-Only figura como No proporcionado, porque no bloquea nada.
- La protección contra marcos figura como Presente con una directiva frame-ancestors limitada a 'none', 'self' o direcciones exactas, o con X-Frame-Options en DENY o SAMEORIGIN.
- X-Content-Type-Options solo figura como Presente con el valor nosniff.
- Referrer-Policy figura como Presente cuando el último valor es no-referrer, same-origin, strict-origin o strict-origin-when-cross-origin. Los navegadores usan el último valor que entienden, así que una lista se evalúa por su última entrada.
- Permissions-Policy figura como Presente con solo enviarse, porque la lista adecuada de funciones depende del sitio.
Qué envían los sitios reales: una muestra
El 2 de noviembre de 2026 solicitamos cinco páginas de inicio con el mismo user agent que usa el comprobador y pasamos las respuestas por las reglas de evaluación de IPNixa. Las cabeceras cambian a menudo, así que tómalo como una instantánea.
| Sitio | HSTS | CSP | Marcos | nosniff | Referrer | Permissions |
|---|---|---|---|---|---|---|
| github.com | presente | revisar | presente | presente | presente | no proporcionado |
| ipnixa.com | presente | revisar | presente | presente | presente | presente |
| www.wikipedia.org | presente | no proporcionado | no proporcionado | no proporcionado | no proporcionado | no proporcionado |
| www.google.com | no proporcionado | Report-Only | presente | no proporcionado | no proporcionado | no proporcionado |
| example.com | no proporcionado | no proporcionado | no proporcionado | no proporcionado | no proporcionado | no proporcionado |
Cómo leer la muestra: revisar no equivale a débil
La política de GitHub limita los scripts a su propio host de recursos y a hashes concretos, lo que es estricto. Solo se marca para revisar porque su style-src permite 'unsafe-inline', y la regla busca esa palabra clave en cualquier parte de la política. Los estilos en línea suponen un riesgo mucho menor que los scripts en línea, así que es una concesión deliberada, no un agujero.
Nuestro propio sitio se marca para revisar por otro motivo: su política solo contiene frame-ancestors 'none', que bloquea la inserción en marcos pero no restringe los scripts. Mostramos el resultado tal como está.
La página de inicio de Google envía su política de scripts como Content-Security-Policy-Report-Only, que informa de las infracciones sin bloquearlas, y no envió HSTS en esta respuesta; los sitios grandes pueden imponer HTTPS por otros medios, como las listas de precarga de los navegadores. El portal de Wikipedia envía un max-age de HSTS muy largo y poco más en esa página. Nada de esto indica si estos sitios son seguros en general; muestra qué salvaguardas del navegador solicita cada respuesta.
Añadir cabeceras a tu propio sitio
Añade las cabeceras de una en una: recarga tu sitio y comprueba que las páginas, los inicios de sesión, los vídeos incrustados y los formularios de pago siguen funcionando antes de añadir la siguiente.
- Empieza por las cabeceras de bajo riesgo: X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin y X-Frame-Options: DENY, salvo que otro sitio deba mostrar tus páginas dentro de un marco.
- Añade HSTS con un max-age corto, como 300, confirma que todos los subdominios funcionan con HTTPS y después súbelo a 31536000. Añade includeSubDomains solo cuando todos los subdominios admitan HTTPS.
- Redacta una Content-Security-Policy y envíala primero como Content-Security-Policy-Report-Only. Recoge los informes de infracciones o revisa la consola del navegador, corrige o permite las fuentes legítimas y luego pasa a la cabecera que aplica la política.
- Añade Permissions-Policy con las funciones sensibles que no usas, por ejemplo camera=(), microphone=(), geolocation=().
- En nginx usa add_header con el indicador always; en Apache, Header always set; y en un alojamiento estático o una CDN, el archivo de cabeceras de la plataforma o sus reglas de cabeceras de respuesta.
- Vuelve a ejecutar la comprobación de cabeceras de IPNixa. Para cada cabecera que falta muestra una línea lista para copiar en nginx, Apache o un archivo _headers.
Precarga HSTS y otras precauciones
Las listas de precarga HSTS vienen integradas en los navegadores, así que incluso la primera visita usa HTTPS. Para enviar un dominio se exige un max-age de al menos un año, includeSubDomains y la directiva preload, y una retirada tarda meses en llegar a los usuarios. Envíalo solo cuando todos los subdominios, incluidos los internos, vayan a seguir en HTTPS.
X-XSS-Protection está obsoleta; los navegadores modernos la ignoran y una CSP la sustituye. El comprobador no evalúa las cabeceras de aislamiento entre orígenes (Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy y Cross-Origin-Resource-Policy), porque solo las necesitan los sitios que usan funciones como la memoria compartida, y activarlas puede bloquear contenido incrustado de terceros.
Preguntas frecuentes
¿Que falte una cabecera significa que no es seguro visitar el sitio?
No. Las cabeceras añaden protección en el navegador contra ataques concretos. Un sitio sin ellas puede estar bien gestionado, y uno que las tenga todas puede tener otros fallos. Usa el resultado como lista de comprobación para el propietario del sitio, no como veredicto para los visitantes.
¿Por qué mi navegador muestra cabeceras que el comprobador no vio?
Los sitios pueden variar las cabeceras según la página, el país, si hay una sesión iniciada o la ubicación de la CDN. El comprobador lee una sola respuesta de la dirección que introduces, obtenida desde la red de Cloudflare sin cookies.
¿Uso X-Frame-Options o frame-ancestors?
frame-ancestors, en CSP, es el control moderno y permite autorizar sitios concretos. Enviar también X-Frame-Options mantiene cubiertos los navegadores antiguos; cuando están los dos, los navegadores actuales siguen frame-ancestors.
¿Puedo comprobar una página que requiere iniciar sesión?
No. El comprobador no envía cookies ni credenciales y rechaza direcciones privadas y locales. Para páginas que requieren iniciar sesión o están en una red privada, copia las cabeceras de respuesta sin procesar desde las herramientas para desarrolladores del navegador o con curl -I y pégalas en el comprobador; las cabeceras pegadas se analizan en tu navegador.