Encabezados de seguridad HTTP: CSP, HSTS, Permissions-Policy y configuración completa Skip to content

Base de conocimiento

Conocimientos prácticos sobre frontend, herramientas de IA y desarrollo de software.

Encabezados de seguridad HTTP: CSP, HSTS, Permissions-Policy y configuración completa

Publicado: 16 min de lectura Escrito por: Security

Los encabezados de seguridad HTTP permiten que el servidor defina reglas para la carga de scripts, el uso de frames, las funciones del dispositivo, la información de referencia, la interpretación de tipos MIME y el acceso mediante HTTPS. Una configuración adecuada reduce el impacto de varias clases de ataques, entre ellas XSS, clickjacking, confusión MIME, XS-Leaks e incrustación cross-origin no autorizada.

No son un cortafuegos y no reparan una autorización defectuosa, API vulnerables, inyección SQL, credenciales filtradas o dependencias obsoletas. Las cabeceras de seguridad son una capa de defensa en profundidad: reducen la superficie de ataque del navegador y restringen lo que puede ocurrir después de que otra debilidad ya haya sido explotada.

En 2026 conviene separar tres categorías:

  1. Cabeceras de referencia que tienen sentido para la mayoría de los sitios web.
  2. Cabeceras dependientes de la arquitectura que pueden romper OAuth, pagos, CDNs, iframes o la entrega de PDF cuando se copian sin análisis.
  3. Cabeceras obsoletas que no deberían habilitarse simplemente para mejorar la puntuación de un escáner desactualizado.

TL;DR: empieza con una Content Security Policy cuidadosamente diseñada, HSTS una vez que HTTPS esté completamente desplegado, X-Content-Type-Options: nosniff, un Referrer-Policy explícito y un Permissions-Policy comedido. Usa CSP frame-ancestors como control anti-framing principal y conserva X-Frame-Options solo como capa de compatibilidad. Despliega COOP, COEP y CORP solo tras revisar las integraciones cross-origin. Elimina o desactiva X-XSS-Protection, Expect-CT, HPKP y la antigua cabecera Report-To.

Las recomendaciones y la compatibilidad se verificaron por última vez el 23 de julio de 2026.

Las principales cabeceras de un vistazo

Cabecera Recomendación habitual Qué limita ¿Usar en todas partes?
Content-Security-Policy política específica de la aplicación, preferiblemente basada en nonce o hash XSS, inyección, orígenes de recursos no aprobados y framing sí para HTML, tras pruebas
Strict-Transport-Security max-age=31536000; includeSubDomains; añade preload solo tras una revisión degradación a HTTP y evasión de errores de certificado sí cuando todo el dominio está preparado para HTTPS
X-Content-Type-Options nosniff MIME sniffing y algunas confusiones de MIME
Referrer-Policy strict-origin-when-cross-origin o más estricta fuga de la ruta y la query de la URL
Permissions-Policy desactivar capacidades sin uso como camera=(), microphone=(), geolocation=() uso de determinadas API del navegador por documentos y frames normalmente, tras probar las funciones
CSP frame-ancestors 'none', 'self' u orígenes explícitos clickjacking y framing no deseado sí para documentos HTML
X-Frame-Options DENY o SAMEORIGIN por compatibilidad framing en implementaciones antiguas a menudo, junto a frame-ancestors
Cross-Origin-Opener-Policy a menudo same-origin, salvo que se necesiten relaciones con popups algunos XS-Leaks y el acceso a window.opener depende de la arquitectura
Cross-Origin-Embedder-Policy require-corp o credentialless, solo de forma deliberada incrustación de recursos cross-origin sin permiso no, no de forma automática
Cross-Origin-Resource-Policy same-origin, same-site o cross-origin según el recurso lecturas cross-origin no-CORS no deseadas depende del recurso
Cache-Control no-store para respuestas muy sensibles; private para contenido personalizado almacenamiento en el navegador y en cachés intermedias para respuestas sensibles
Set-Cookie Secure; HttpOnly; SameSite=Lax/Strict según corresponda robo y envío cross-site inadecuado de cookies para cookies de sesión
Reporting-Endpoints endpoint para informes de CSP/COOP/COEP observabilidad de las políticas opcional
X-XSS-Protection omitir o establecer en 0 filtro XSS heredado no habilitar
Expect-CT eliminar mecanismo obsoleto de Certificate Transparency no
Public-Key-Pins no usar fijación histórica de certificados (pinning) no

OWASP considera las cabeceras de respuesta como valiosos controles de hardening, al tiempo que subraya que cada valor debe corresponder al tipo de respuesta y a la arquitectura de la aplicación.

Un punto de partida mínimo

Esto es una plantilla inicial, no una respuesta universal para copiar y pegar:

Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: https:; font-src 'self'; style-src 'self'; script-src 'self'; connect-src 'self'; upgrade-insecure-requests
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Frame-Options: DENY

Esta política bloquea los scripts y estilos inline, los orígenes de recursos no listados, el framing, los formularios enviados a otros orígenes, el acceso a cámara/micrófono/geolocalización y la navegación HTTP una vez que HSTS se ha almacenado.

Si el sitio usa fuentes externas, analítica, mapas, widgets de pago, OAuth, gestores de etiquetas, API de terceros o código inline, la política debe adaptarse.

1. Content-Security-Policy: la cabecera más potente y difícil

Content-Security-Policy define desde dónde puede el navegador cargar scripts, estilos, imágenes, fuentes, frames y conexiones de red. Una CSP correcta puede reducir sustancialmente el impacto del XSS y de la inyección de datos, pero no sustituye la validación de entradas, la codificación de salidas ni las API seguras del DOM.

Directivas principales

Directiva Propósito Valor inicial habitual
default-src alternativa para tipos de recursos sin una directiva dedicada 'self'
script-src scripts permitidos nonce o hashes, opcionalmente 'self'
style-src estilos permitidos 'self', nonce o hashes
img-src imágenes 'self' data: https:
font-src fuentes 'self' y orígenes explícitos de CDN
connect-src Fetch, XHR, WebSocket y EventSource tu API y endpoints explícitos
frame-src frames incrustados por la página solo los orígenes necesarios
frame-ancestors qué páginas padre pueden incrustar esta página 'none' o 'self'
form-action destinos válidos de formularios 'self' o endpoints explícitos
base-uri URLs de <base> permitidas 'self' o 'none'
object-src plugins <object> y <embed> 'none'
upgrade-insecure-requests reescribir los subrecursos HTTP a HTTPS sin valor

Listas de permitidos frente a una CSP estricta

Una lista de dominios permitidos puede volverse frágil. Un CDN de confianza puede alojar muchos archivos sin relación entre sí, y un cargador de terceros puede traer dependencias adicionales de forma dinámica. web.dev recomienda una CSP estricta basada en nonces o hashes; strict-dynamic permite que los scripts cargados por un script de confianza hereden esa confianza.

Ejemplo de política con nonce:

Content-Security-Policy:
  default-src 'self';
  base-uri 'self';
  object-src 'none';
  frame-ancestors 'none';
  form-action 'self';
  script-src 'nonce-{RANDOM_NONCE}' 'strict-dynamic';
  style-src 'self' 'nonce-{RANDOM_NONCE}';
  img-src 'self' data: https:;
  font-src 'self';
  connect-src 'self' https://api.example.com;
  upgrade-insecure-requests

HTML correspondiente:

<script nonce="{RANDOM_NONCE}">
  window.__APP_CONFIG__ = { apiUrl: "https://api.example.com" };
</script>

Un nonce debe ser impredecible, único para cada respuesta HTML, estar presente en la cabecera y en los elementos de confianza, y ser generado por el servidor. Un nonce constante almacenado en la configuración no proporciona la protección prevista. Para páginas estáticas que no pueden generar un valor nuevo por petición, los hashes pueden resultar más prácticos.

Evita unsafe-inline y unsafe-eval

'unsafe-inline' en script-src permite JavaScript inline y debilita en gran medida la protección contra XSS. 'unsafe-eval' habilita API que ejecutan cadenas como código, incluidos eval() y el constructor Function.

No los añadas solo para silenciar las violaciones de la consola. En su lugar:

  1. traslada el código inline a archivos externos;
  2. usa un nonce o hash;
  3. identifica la dependencia que requiere eval;
  4. busca una configuración de compilación o de librería distinta.

Trusted Types

Una política como:

Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-policy

puede exigir valores tipados en determinados sinks de DOM XSS como innerHTML. Desde febrero de 2026, require-trusted-types-for está disponible en los principales navegadores actuales, aunque las versiones más antiguas pueden no admitirlo.

Trusted Types es una defensa avanzada. La aplicación debe definir políticas de transformación seguras, y los frameworks y dependencias deben ser compatibles. Añadir solo la cabecera no es suficiente.

Empieza con Report-Only

Un despliegue más seguro comienza con:

Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; report-to csp-endpoint
Reporting-Endpoints: csp-endpoint="https://example.com/security/csp-reports"

Content-Security-Policy-Report-Only informa de las violaciones sin bloquear recursos, lo que permite identificar orígenes que faltan y flujos rotos antes de la aplicación efectiva. Reporting-Endpoints reemplaza a la cabecera obsoleta Report-To y debería preferirse en los despliegues actuales.

Un endpoint de informes debería imponer límites de tamaño de payload, limitación de tasa, registro seguro, codificación de salidas y un periodo de retención corto y específico para su finalidad. Los informes de CSP pueden contener URLs y detalles de recursos.

2. Strict-Transport-Security: HTTPS sin vía de degradación

HSTS indica al navegador que un host debe contactarse únicamente por HTTPS. Una vez almacenado, el navegador promociona los futuros intentos HTTP e impide que los usuarios evadan algunos errores de certificado.

Strict-Transport-Security: max-age=31536000; includeSubDomains
  • max-age=31536000 almacena la política durante un año.
  • includeSubDomains cubre los subdominios.
  • preload indica la intención de unirse a la lista de preload del navegador.

No empieces con preload

Un despliegue de HSTS erróneo puede dejar fuera a usuarios legítimos. Un subdominio antiguo solo HTTP, un certificado caducado o un servicio de terceros bajo tu dominio pueden hacer que includeSubDomains y un max-age largo resulten peligrosos.

Un despliegue prudente puede usar:

5 minutes → 1 day → 1 week → 1 month → 1 year

En cada etapa prueba el dominio apex, los subdominios activos, los certificados wildcard y SAN, los servicios heredados, los paneles de administración, las API y los endpoints de socios.

El preload de HSTS requiere un certificado válido, redirecciones de HTTP a HTTPS, un max-age suficientemente largo, includeSubDomains y el token preload. La eliminación puede tardar semanas porque la lista se distribuye dentro de los navegadores.

3. X-Content-Type-Options: detén la adivinación de MIME

X-Content-Type-Options: nosniff

Esto indica al navegador que respete el Content-Type declarado en lugar de reinterpretar una respuesta como otro tipo. Los scripts y estilos pueden bloquearse cuando su tipo MIME no coincide con el esperado.

No sustituye una configuración correcta del servidor. Las respuestas siguen necesitando valores precisos:

Content-Type: text/html; charset=utf-8
Content-Type: text/css; charset=utf-8
Content-Type: application/javascript; charset=utf-8
Content-Type: application/json; charset=utf-8
Content-Type: image/avif

Esto es especialmente importante para las subidas de usuarios, los endpoints de descarga, los archivos generados dinámicamente, el almacenamiento de objetos, los CDNs y las respuestas de error que podrían devolver HTML en lugar de JSON.

4. Referrer-Policy: reduce la fuga de URLs

Referrer-Policy controla qué parte de la URL de la página actual puede enviarse en la cabecera Referer al solicitar otro recurso.

Un valor predeterminado razonable es:

Referrer-Policy: strict-origin-when-cross-origin

Envía la URL completa en las peticiones same-origin, solo el origen en las peticiones HTTPS cross-origin y ningún referente en una degradación de HTTPS a HTTP.

Entre las alternativas más estrictas están:

Referrer-Policy: no-referrer

o:

Referrer-Policy: same-origin

La elección puede afectar a la analítica, a los sistemas de afiliación y a los proveedores de pago. Los secretos, tokens, direcciones de correo y datos personales no deberían colocarse en URLs desde un principio.

5. Protección contra clickjacking: frame-ancestors y X-Frame-Options

El control más flexible es CSP:

Content-Security-Policy: frame-ancestors 'none'

o:

Content-Security-Policy: frame-ancestors 'self' https://portal.partner.example

frame-ancestors define qué páginas padre pueden incrustar un documento en <frame>, <iframe>, <object> o <embed>.

Por compatibilidad, añade:

X-Frame-Options: DENY

o:

X-Frame-Options: SAMEORIGIN

MDN recomienda frame-ancestors para los despliegues modernos porque es más expresiva. ALLOW-FROM es obsoleto y puede hacer que los navegadores actuales ignoren la cabecera. X-Frame-Options debe ser una cabecera HTTP; una versión <meta http-equiv> no tiene efecto.

6. Permissions-Policy: desactiva las capacidades que el sitio no usa

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

La cabecera controla el acceso de un documento y sus frames a determinadas capacidades del navegador, incluidas la cámara, el micrófono y la geolocalización.

Permitir el origen actual:

Permissions-Policy: geolocation=(self), camera=(), microphone=()

O permitir un origen explícito:

Permissions-Policy: geolocation=(self "https://maps.example")

No copies una lista enorme con todas las directivas conocidas. Las directivas individuales tienen distinto soporte en los navegadores y algunas siguen siendo experimentales. Identifica las capacidades que usa la aplicación y luego desactiva explícitamente las relevantes que no se utilicen.

7. COOP, COEP y CORP: el aislamiento cross-origin no es un valor predeterminado universal

Estas cabeceras están relacionadas pero resuelven problemas distintos.

Cross-Origin-Opener-Policy

Cross-Origin-Opener-Policy: same-origin

COOP controla si los documentos abiertos mediante navegación o window.open() comparten un grupo de contexto de navegación. same-origin separa el documento de los abridores cross-origin y mitiga algunos XS-Leaks.

Puede romper los popups de OAuth, las ventanas de pago y las integraciones que dependen de window.opener. En algunos casos resulta más apropiado esto:

Cross-Origin-Opener-Policy: same-origin-allow-popups

Cross-Origin-Embedder-Policy

Cross-Origin-Embedder-Policy: require-corp

COEP exige que los recursos cross-origin no-cors concedan permiso a través de CORP o que se obtengan con CORS. La ausencia de cabeceras puede bloquear imágenes, fuentes, scripts, frames y otros recursos de terceros.

Una alternativa es:

Cross-Origin-Embedder-Policy: credentialless

Esto permite algunos recursos no-cors sin CORP explícito y, al mismo tiempo, elimina credenciales como las cookies.

Cross-Origin-Resource-Policy

Cross-Origin-Resource-Policy: same-origin

CORP es una política sobre el propio recurso y puede usar:

  • same-origin,
  • same-site,
  • cross-origin.

No sustituye a CORS. MDN también documenta un problema de Chrome relacionado con la renderización parcial de PDF bajo algunos despliegues de CORP, por lo que la cabecera no debería aplicarse de forma global sin pruebas.

El par:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

habilita el aislamiento cross-origin que exigen determinadas API avanzadas, incluido el acceso completo a SharedArrayBuffer. No lo despliegues únicamente para la puntuación de un escáner.

8. Cookies seguras y caché

Set-Cookie y Cache-Control no siempre figuran como cabeceras de seguridad, pero protegen directamente las sesiones y los datos sensibles.

Cookie de sesión

Set-Cookie: __Host-session=RANDOM_VALUE; Path=/; Secure; HttpOnly; SameSite=Lax
  • Secure restringe la transmisión a HTTPS.
  • HttpOnly impide el acceso desde JavaScript.
  • SameSite limita el envío cross-site.
  • __Host- requiere Secure, Path=/ y ningún Domain, vinculando la cookie de forma más estrecha al host.

SameSite=Strict es más fuerte pero puede interrumpir los retornos desde proveedores de inicio de sesión o de pago. SameSite=None requiere Secure y solo debería usarse para una cookie genuinamente cross-site.

Respuestas sensibles

Cache-Control: no-store

Esto pide a las cachés privadas y compartidas que no almacenen la respuesta. El contenido personalizado que puede almacenarse en el navegador pero no en los intermediarios puede usar:

Cache-Control: private, no-cache

MDN recomienda marcar explícitamente como private las respuestas personalizadas para evitar un almacenamiento compartido accidental.

9. Reduce la divulgación de tecnología

Cabeceras como:

Server: nginx/1.24.0
X-Powered-By: PHP/8.4
X-AspNet-Version: 4.0.30319

facilitan el fingerprinting. Eliminarlas no oculta el stack ante un atacante decidido, pero evita la divulgación directa de la versión.

  • elimina X-Powered-By;
  • desactiva las cabeceras de versión del framework;
  • limita el detalle en Server;
  • no publiques una versión falsa de forma deliberada;
  • no confundas la oscuridad con la aplicación de parches.

OWASP recomienda eliminar X-Powered-By y limitar Server, señalando al mismo tiempo que las tecnologías todavía pueden inferirse por otras vías.

10. Cabeceras obsoletas y consejos engañosos

X-XSS-Protection

No habilites:

X-XSS-Protection: 1; mode=block

OWASP advierte de que los filtros XSS heredados pueden crear vulnerabilidades en páginas que de otro modo serían seguras. Omite la cabecera o desactívala explícitamente:

X-XSS-Protection: 0

Usa en su lugar CSP, codificación de salidas y API seguras.

Expect-CT

Expect-CT es obsoleta en la práctica porque los clientes actuales requieren Certificate Transparency para los certificados modernos. MDN la describe como prácticamente obsoleta desde junio de 2021.

Public-Key-Pins

HPKP no debería desplegarse. Un pin erróneo podría dejar fuera a los usuarios durante mucho tiempo y la cabecera se ha eliminado de los navegadores modernos. Es preferible un TLS correcto, la renovación automatizada, CAA, la monitorización de certificados y un preload de HSTS cuidadosamente revisado.

Report-To

La antigua:

Report-To: { ... }

está obsoleta. Usa:

Reporting-Endpoints: csp="https://example.com/reports/csp"

Access-Control-Allow-Origin: *

CORS no es un conjunto de cabeceras de hardening para añadir de forma global. Access-Control-Allow-Origin relaja la Same-Origin Policy. Las respuestas de API con credenciales no pueden combinar de forma segura el comodín * con el acceso cross-origin autenticado. Permite solo los orígenes necesarios y valídalos en el servidor.

11. Ejemplos de configuración de servidor

Nginx

add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: https:; style-src 'self'; script-src 'self'; connect-src 'self'; upgrade-insecure-requests" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header X-Frame-Options "DENY" always;

always importa porque mantiene las cabeceras en las respuestas de error y de estado no estándar.

Apache

<IfModule mod_headers.c>
  Header always set Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: https:; style-src 'self'; script-src 'self'; connect-src 'self'; upgrade-insecure-requests"
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
  Header always set X-Frame-Options "DENY"
</IfModule>

PHP

<?php

header("Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: https:; style-src 'self'; script-src 'self'; connect-src 'self'; upgrade-insecure-requests");
header("Strict-Transport-Security: max-age=31536000; includeSubDomains");
header("X-Content-Type-Options: nosniff");
header("Referrer-Policy: strict-origin-when-cross-origin");
header("Permissions-Policy: camera=(), microphone=(), geolocation=()");
header("X-Frame-Options: DENY");

Las cabeceras deben enviarse antes del cuerpo de la respuesta. Genera un nonce criptográficamente aleatorio por separado para cada petición.

Node.js / Express

app.use((req, res, next) => {
  res.setHeader(
    "Content-Security-Policy",
    "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: https:; style-src 'self'; script-src 'self'; connect-src 'self'; upgrade-insecure-requests"
  );
  res.setHeader(
    "Strict-Transport-Security",
    "max-age=31536000; includeSubDomains"
  );
  res.setHeader("X-Content-Type-Options", "nosniff");
  res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
  res.setHeader(
    "Permissions-Policy",
    "camera=(), microphone=(), geolocation=()"
  );
  res.setHeader("X-Frame-Options", "DENY");
  res.removeHeader("X-Powered-By");
  next();
});

Un sitio que use CDNs, WebSockets, OAuth, pagos o mapas necesitará una CSP más amplia pero igualmente explícita.

12. Un proceso de despliegue que evita caídas

Inventario

Enumera todos los orígenes de scripts, estilos, fuentes e imágenes; los endpoints de API y WebSocket; los iframes; los popups de OAuth/pago; los recursos de CDN; las subidas de usuarios; los subdominios de HSTS y las capacidades del navegador que usa la aplicación.

Observa

  • ejecuta CSP en Report-Only;
  • recopila informes y violaciones de la consola del navegador;
  • prueba cada ruta de usuario crítica;
  • incluye navegadores móviles y compatibles;
  • inspecciona las páginas de error, las redirecciones y los recursos estáticos.

Aplica de forma gradual

  • empieza con object-src, base-uri, frame-ancestors y form-action;
  • pasa a los recursos estáticos;
  • aplica un script-src estricto en último lugar;
  • incrementa el max-age de HSTS de forma gradual;
  • prueba COOP/COEP por separado frente a las integraciones de popup y cross-origin.

Vigila las regresiones

Las pruebas de CI deberían obtener URLs representativas, detectar cabeceras duplicadas o en conflicto, confirmar los tipos MIME, detectar la eliminación accidental de CSP/HSTS y ejecutar flujos de inicio de sesión y de pago de extremo a extremo.

13. Cómo probar las cabeceras

Comprueba la respuesta directamente:

curl -I https://example.com/

Sigue las redirecciones:

curl -IL https://example.com/

Inspecciona un recurso específico:

curl -I https://example.com/assets/app.js

Verifica las cabeceras en la página de inicio, el inicio de sesión y las respuestas 404 y 500; confirma que CSP no esté duplicada con políticas en conflicto; asegúrate de que HSTS se envíe solo por HTTPS; comprueba los tipos MIME; y verifica que un CDN o un proxy inverso no haya eliminado las cabeceras.

El Security Headers Inspector gratuito de POLPROG comprueba HSTS, CSP, la protección frente a framing y otros controles. Usa el DNS & SSL Inspector para comprobaciones de certificado y DNS, y Website Health Check para una revisión más amplia de SEO, rendimiento, accesibilidad y seguridad.

Lista de comprobación para el despliegue

CSP

  • default-src restrictivo.
  • object-src 'none'.
  • base-uri limitado.
  • frame-ancestors coincide con el modelo de incrustación real.
  • form-action restringe los destinos de los formularios.
  • El código inline usa un nonce o hash cuando es necesario.
  • El nonce es único por respuesta.
  • Sin 'unsafe-inline' injustificado.
  • Sin 'unsafe-eval' injustificado.
  • Política probada primero en Report-Only.
  • El endpoint de informes tiene límites de tasa y retención limitada.

HTTPS y HSTS

  • Cada página y recurso funciona por HTTPS.
  • HTTP redirige directamente a HTTPS.
  • Los certificados están monitorizados.
  • Todos los subdominios están inventariados.
  • max-age incrementado por etapas.
  • includeSubDomains es seguro.
  • preload añadido solo tras revisar las consecuencias.

Otros controles

  • X-Content-Type-Options: nosniff.
  • Content-Type correcto en cada respuesta.
  • Referrer-Policy explícito.
  • Permissions-Policy desactiva las capacidades sin uso.
  • Sin ALLOW-FROM en X-Frame-Options.
  • COOP no rompe OAuth ni los pagos.
  • COEP no bloquea los recursos de terceros necesarios.
  • CORP coincide con el modelo de compartición de cada recurso.
  • Las cookies de sesión usan Secure, HttpOnly y un SameSite apropiado.
  • Las respuestas sensibles usan un Cache-Control correcto.
  • Se eliminan las cabeceras de versión de tecnología.
  • X-XSS-Protection está ausente o desactivada.
  • Expect-CT, HPKP y la antigua Report-To están eliminadas.

Veredicto

Para la mayoría de los sitios web corporativos y aplicaciones web, el orden correcto es:

  1. HTTPS correcto, tipos MIME y cookies seguras.
  2. Una CSP específica de la aplicación desplegada mediante Report-Only.
  3. HSTS desplegado por etapas.
  4. nosniff, Referrer-Policy, Permissions-Policy y protección frente a framing.
  5. COOP, COEP y CORP solo cuando se comprende el modelo cross-origin.
  6. Eliminación de las cabeceras obsoletas y que filtran información.

El mejor conjunto de cabeceras de seguridad no es el más largo. Es la política más pequeña que se ajusta con precisión a la aplicación, supera las pruebas de la ruta crítica y sigue monitorizándose después de cada despliegue.

HTTP Headers Security CSP HSTS Web Security

Preguntas frecuentes

¿Las cabeceras de seguridad previenen todos los ataques?

No. Restringen el comportamiento del navegador y mitigan determinadas clases de vulnerabilidad, pero no sustituyen la autorización, la validación, la aplicación de parches a las dependencias, la gestión de secretos ni las pruebas de seguridad.

¿Qué cabecera es la más importante?

Para las páginas HTML, una CSP bien diseñada es la que tiene mayor potencial. También es fácil de romper, por lo que debería empezar en modo Report-Only.

¿Puedo copiar una CSP ya hecha?

Úsala solo como punto de partida. La política debe representar los scripts, las API, las fuentes, los frames, los formularios y las integraciones que usa la aplicación real.

¿Sigue siendo necesaria X-Frame-Options?

CSP frame-ancestors es el control moderno y flexible. DENY o SAMEORIGIN pueden mantenerse como capa de compatibilidad. No uses ALLOW-FROM.

¿Se puede establecer HSTS en dos años de inmediato?

Técnicamente sí, pero es arriesgado antes de haber comprobado cada subdominio, certificado y servicio heredado. Incrementa max-age de forma gradual.

¿Debería usar el preload de HSTS?

Solo cuando todo el dominio y todos los subdominios estén preparados para HTTPS de forma permanente. Eliminar una entrada con preload es más lento que borrar una política HSTS almacenada en la caché del navegador.

¿Permissions Policy funciona igual en todos los navegadores?

No. Las directivas individuales tienen distintos niveles de soporte y algunas son experimentales. Prueba las capacidades que realmente configures.

¿Deberían habilitarse COEP y CORP de forma global?

No de forma automática. Pueden bloquear imágenes, fuentes, scripts, iframes y archivos PDF de terceros. Inventaría primero los recursos cross-origin y revisa su comportamiento con CORS/CORP.

¿Por qué un escáner penaliza la ausencia de X-XSS-Protection?

Algunos escáneres usan reglas desactualizadas. La recomendación actual de OWASP es omitirla o establecerla en 0.

¿Puede CSP romper un sitio web?

Sí. Una política demasiado restrictiva puede bloquear scripts, estilos, fuentes, API, el inicio de sesión y los pagos. Empieza con Content-Security-Policy-Report-Only.

¿Las páginas de error deberían incluir las cabeceras?

Sí, cuando sean relevantes para ese tipo de respuesta. Las páginas de error HTML no deberían perder CSP, nosniff, Referrer-Policy ni la protección frente a framing.

Fuentes y notas al pie

  1. OWASP Cheat Sheet Series, HTTP Security Response Headerslectura complementaria
  2. MDN Web Docs, Content Security Policylectura complementaria
  3. web.dev, Mitigate cross-site scripting with a strict Content Security Policylectura complementaria
  4. MDN Web Docs, CSP require-trusted-types-forlectura complementaria
  5. MDN Web Docs, Content-Security-Policy-Report-Onlylectura complementaria
  6. MDN Web Docs, Reporting-Endpointslectura complementaria
  7. MDN Web Docs, Strict-Transport-Securitylectura complementaria
  8. OWASP Cheat Sheet Series, HTTP Strict Transport Securitylectura complementaria
  9. HSTS Preload, Submission Requirementslectura complementaria
  10. MDN Web Docs, X-Content-Type-Optionslectura complementaria
  11. MDN Web Docs, Referrer-Policylectura complementaria
  12. MDN Web Docs, CSP frame-ancestorslectura complementaria
  13. MDN Web Docs, X-Frame-Optionslectura complementaria
  14. MDN Web Docs, Permissions-Policylectura complementaria
  15. MDN Web Docs, Cross-Origin-Opener-Policylectura complementaria
  16. MDN Web Docs, Cross-Origin-Embedder-Policylectura complementaria
  17. MDN Web Docs, Cross-Origin Resource Policylectura complementaria
  18. MDN Web Docs, Set-Cookielectura complementaria
  19. MDN Web Docs, Cache-Controllectura complementaria
  20. MDN Web Docs, Expect-CTlectura complementaria
  21. POLPROG, Security Headers Inspectorlectura complementaria

¿Te ha resultado útil?

Recibe nuevos artículos por email

Un correo breve por cada nuevo artículo de la base de conocimiento. Sin spam, te das de baja con un clic.

Solo usamos tu email para enviar nuevos artículos. Sin compartir con terceros.

Volver a la base de conocimiento