Obtén más información sobre los encabezados que pueden mantener tu sitio seguro y consulta rápidamente los detalles más importantes.
En este artículo, se enumeran los encabezados de seguridad más importantes que puedes usar para proteger tu sitio web. Úsala para comprender las funciones de seguridad basadas en la Web, aprender a implementarlas en tu sitio web y como referencia cuando necesites un recordatorio.
- Encabezados de seguridad recomendados para sitios web que manejan datos sensibles de los usuarios:
- Política de Seguridad del Contenido (CSP)
- Tipos de confianza
- Encabezados de seguridad recomendados para todos los sitios web:
- X-Content-Type-Options
- X-Frame-Options
- Política de recursos de origen cruzado (CORP)
- Política de apertura de origen cruzado (COOP)
- HTTP con Seguridad de Transporte Estricta (HSTS)
- Encabezados de seguridad para sitios web con funciones avanzadas:
- Uso compartido de recursos entre dominios (CORS)
- Política de incorporador de origen cruzado (COEP)
Antes de profundizar en los encabezados de seguridad, obtén información sobre las amenazas conocidas en la Web y por qué querrías usar estos encabezados de seguridad.
Protege tu sitio de las vulnerabilidades de inyección
Las vulnerabilidades de inyección surgen cuando los datos no confiables que procesa tu aplicación pueden afectar su comportamiento y, por lo general, provocar la ejecución de secuencias de comandos controladas por atacantes. La vulnerabilidad más común que causan los errores de inyección es la secuencia de comandos entre sitios (XSS) en sus diversas formas, incluidas la XSS reflejada, la XSS almacenada, la XSS basada en DOM y otras variantes.
Por lo general, una vulnerabilidad de XSS puede otorgar a un atacante acceso completo a los datos del usuario que procesa la aplicación y a cualquier otra información alojada en el mismo origen web.
Las defensas tradicionales contra las inyecciones incluyen el uso coherente de sistemas de plantillas HTML con escape automático, evitar el uso de APIs de JavaScript peligrosas y procesar correctamente los datos del usuario alojando las cargas de archivos en un dominio independiente y limpiando el código HTML controlado por el usuario.
- Usa la Política de Seguridad del Contenido (CSP) para controlar qué secuencias de comandos puede ejecutar tu aplicación para mitigar el riesgo de inyecciones.
- Usa Trusted Types para aplicar la limpieza de los datos que se pasan a las APIs de JavaScript peligrosas.
- Usa X-Content-Type-Options para evitar que el navegador interprete de forma incorrecta los tipos de MIME de los recursos de tu sitio web, lo que puede provocar la ejecución de secuencias de comandos.
Aísla tu sitio de otros sitios web
La apertura de la Web permite que los sitios web interactúen entre sí de maneras que pueden infringir las expectativas de seguridad de una aplicación. Esto incluye realizar solicitudes autenticadas de forma inesperada o incorporar datos de otra aplicación en el documento del atacante, lo que le permite modificar o leer datos de la aplicación.
Entre las vulnerabilidades comunes que debilitan el aislamiento web, se incluyen el clickjacking, la falsificación de solicitudes entre sitios (CSRF), la inclusión de secuencias de comandos entre sitios (XSSI) y varias filtraciones entre sitios.
- Usa X-Frame-Options para evitar que un sitio web malicioso incorpore tus documentos.
- Usa la Política de recursos de origen cruzado (CORP) para evitar que un sitio web de origen cruzado incluya los recursos de tu sitio web.
- Usa la política de apertura de origen cruzado (COOP) para proteger las ventanas de tu sitio web de las interacciones de sitios web maliciosos.
- Usa el uso compartido de recursos entre dominios (CORS) para controlar el acceso a los recursos de tu sitio web desde documentos de origen cruzado.
Post-Spectre Web Development es una excelente lectura si te interesan estos encabezados.
Crea un sitio web potente de forma segura
Spectre hace que cualquier dato cargado en el mismo grupo de contexto de navegación sea potencialmente legible, a pesar de la política del mismo origen. Los navegadores restringen las funciones
que podrían aprovechar la vulnerabilidad detrás de un entorno especial llamado
"aislamiento de origen cruzado". Con el aislamiento de origen cruzado, puedes
usar funciones potentes, como SharedArrayBuffer.
- Usa la Política de incorporaciones de origen cruzado (COEP) junto con la COOP para habilitar el aislamiento de origen cruzado.
Encripta el tráfico a tu sitio
Los problemas de encriptación aparecen cuando una aplicación no encripta por completo los datos en tránsito, lo que permite que los atacantes que realizan escuchas no autorizadas obtengan información sobre las interacciones del usuario con la aplicación.
La encriptación insuficiente puede surgir en los siguientes casos: no usar HTTPS,
contenido mixto, configurar cookies sin el atributo Secure
(o el prefijo __Secure)
o lógica de validación de CORS laxa.
- Usa la Seguridad de Transporte Estricta de HTTP (HSTS) para entregar tu contenido de forma coherente a través de HTTPS.
Política de Seguridad del Contenido (CSP)
La secuencia de comandos entre sitios (XSS) es un ataque en el que una vulnerabilidad en un sitio web permite que se inserte y ejecute una secuencia de comandos maliciosa.
Content-Security-Policy proporciona una capa adicional para mitigar los ataques de XSS, ya que
restringe las secuencias de comandos que puede ejecutar la página.
Se recomienda que habilites la CSP estricta con uno de los siguientes enfoques:
- Si renderizas tus páginas HTML en el servidor, usa una CSP estricta basada en nonce.
- Si tu HTML se debe entregar de forma estática o almacenarse en caché, por ejemplo, si es una aplicación de una sola página, usa una CSP estricta basada en hash.
Ejemplo de uso: Una CSP basada en nonce
Content-Security-Policy:
script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline';
object-src 'none';
base-uri 'none';
Usos recomendados
1. Usa una CSP estricta basada en nonce {: #nonce-based-csp}
Si renderizas tus páginas HTML en el servidor, usa una CSP estricta basada en nonce.
Genera un nuevo valor de nonce de secuencia de comandos para cada solicitud en el servidor y establece el siguiente encabezado:
archivo de configuración del servidor
Content-Security-Policy: script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none';
En HTML, para cargar las secuencias de comandos, establece el atributo nonce de todas las etiquetas <script> en la misma cadena {RANDOM1}.
index.html
<script nonce="{RANDOM1}" src="https://example.com/script1.js"></script>
<script nonce="{RANDOM1}">
// Inline scripts can be used with the <code>nonce</code> attribute.
</script>Google Fotos es un buen ejemplo de CSP estricta basada en nonce. Usa las Herramientas para desarrolladores para ver cómo se usa.
2. Usa una CSP estricta basada en hash {: #hash-based-csp}
Si tu HTML se debe entregar de forma estática o almacenarse en caché, por ejemplo, si estás compilando una aplicación de una sola página, usa una CSP estricta basada en hash.
archivo de configuración del servidor
Content-Security-Policy: script-src 'sha256-{HASH1}' 'sha256-{HASH2}' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none';
En HTML, deberás intercalar tus secuencias de comandos para aplicar una política basada en hash, ya que la mayoría de los navegadores no admiten el hash de secuencias de comandos externas.
index.html
<script> ...// your script1, inlined </script> <script> ...// your script2, inlined </script>
Para cargar secuencias de comandos externas, lee "Carga secuencias de comandos de origen de forma dinámica" en la sección Opción B: Encabezado de respuesta de CSP basado en hash.
CSP Evaluator es una buena herramienta para evaluar tu CSP, pero, al mismo tiempo, es un buen ejemplo de CSP estricta basada en nonce. Usa las Herramientas para desarrolladores para ver cómo se usa.
Navegadores compatibles
Otros aspectos que debes tener en cuenta sobre la CSP
- La directiva
frame-ancestorsprotege tu sitio contra el secuestro de clics, un riesgo que surge si permites que sitios no confiables incorporen el tuyo. Si prefieres una solución más sencilla, puedes usarX-Frame-Optionspara bloquear la carga, peroframe-ancestorste brinda una configuración avanzada para permitir solo orígenes específicos como incorporadores. - Es posible que hayas usado una CSP para asegurarte de que todos los recursos de tu sitio se carguen a través de HTTPS. Esto se volvió menos relevante: hoy en día, la mayoría de los navegadores bloquean el contenido mixto.
- También puedes establecer una CSP en el modo de solo informes.
- Si no puedes establecer una CSP como un encabezado del servidor, también puedes establecerla como una metaetiqueta. Ten en cuenta que no puedes usar el modo solo de informes para las metaetiquetas (aunque esto puede cambiar).
Más información
Tipos de confianza
La XSS basada en DOM es un ataque en el que se pasan datos maliciosos a un receptor que admite la ejecución de código dinámico, como eval() o .innerHTML.
Los tipos de confianza proporcionan las herramientas para escribir, revisar la seguridad y mantener las aplicaciones sin XSS del DOM. Se pueden habilitar a través de la CSP y hacer que el código JavaScript sea seguro de forma predeterminada, ya que limitan las APIs web peligrosas para que solo acepten un objeto especial: un tipo de confianza.
Para crear estos objetos, puedes definir políticas de seguridad en las que puedes asegurarte de que las reglas de seguridad (como el escape o la limpieza) se apliquen de forma coherente antes de que los datos se escriban en el DOM. Estas políticas son los únicos lugares en el código que podrían introducir DOM XSS.
Ejemplos de uso
Content-Security-Policy: require-trusted-types-for 'script'
// Feature detection
if (window.trustedTypes && trustedTypes.createPolicy) {
// Name and create a policy
const policy = trustedTypes.createPolicy('escapePolicy', {
createHTML: str => {
return str.replace(/\</g, '<').replace(/>/g, '>');
}
});
}
// Assignment of raw strings is blocked by Trusted Types.
el.innerHTML = 'some string'; // This throws an exception.
// Assignment of Trusted Types is accepted safely.
const escaped = policy.createHTML('<img src=x onerror=alert(1)>');
el.innerHTML = escaped; // '&lt;img src=x onerror=alert(1)&gt;'
Usos recomendados
-
Aplicar Trusted Types para receptores de DOM peligrosos Encabezado de CSP y Trusted Types:
Content-Security-Policy: require-trusted-types-for 'script'Actualmente,
'script'es el único valor aceptable para la directivarequire-trusted-types-for.Por supuesto, puedes combinar los tipos de confianza con otras directivas de CSP:
Combinación de una CSP basada en nonce de arriba con Trusted Types:
Content-Security-Policy:
script-src 'nonce-{RANDOM1}' 'strict-dynamic' https: 'unsafe-inline';
object-src 'none';
base-uri 'none';
require-trusted-types-for 'script';
<aside class="note"><b>Nota: </b> Puedes limitar los nombres de políticas de tipos de confianza permitidos configurando una directiva <code>trusted-types</code> adicional (por ejemplo, <code>trusted-types myPolicy</code>). Sin embargo, esto no es un requisito. </aside>
-
Define una política
Política:
// Feature detection if (window.trustedTypes && trustedTypes.createPolicy) { // Name and create a policy const policy = trustedTypes.createPolicy('escapePolicy', { createHTML: str => { return str.replace(/\/g, '>'); } }); }
-
Aplica la política
Usa la política cuando escribas datos en el DOM:
// Assignment of raw strings are blocked by Trusted Types. el.innerHTML = 'some string'; // This throws an exception.</p> <p>// Assignment of Trusted Types is accepted safely. const escaped = policy.createHTML('<img src="x" onerror="alert(1)">'); el.innerHTML = escaped; // '<img src=x onerror=alert(1)>'
Con
require-trusted-types-for 'script', es obligatorio usar un tipo de confianza. Si usas cualquier API de DOM peligrosa con una cadena, se producirá un error.
Navegadores compatibles
Más información
- Evita las vulnerabilidades de secuencias de comandos entre sitios basadas en el DOM con Trusted Types
- CSP: require-trusted-types-for - HTTP | MDN
- CSP: trusted-types - HTTP | MDN
- Demostración de Trusted Types: Abre el inspector de Herramientas para desarrolladores y observa qué sucede.
X-Content-Type-Options
Cuando se entrega un documento HTML malicioso desde tu dominio (por ejemplo, si una imagen subida a un servicio de fotos contiene lenguaje de marcado HTML válido), algunos navegadores lo tratarán como un documento activo y permitirán que ejecute secuencias de comandos en el contexto de la aplicación, lo que generará un error de secuencia de comandos entre sitios.
X-Content-Type-Options: nosniff lo evita, ya que le indica al navegador que
el tipo de MIME establecido en el
encabezado Content-Type para una respuesta determinada es correcto. Este encabezado se recomienda para todos tus recursos.
Ejemplo de uso
X-Content-Type-Options: nosniff
Usos recomendados
Se recomienda X-Content-Type-Options: nosniff para todos los recursos que se entregan desde
tu servidor junto con el encabezado Content-Type correcto.
Ejemplo de encabezados enviados con un documento HTML
X-Content-Type-Options: nosniff Content-Type: text/html; charset=utf-8
Navegadores compatibles
Más información
X-Frame-Options
Si un sitio web malicioso puede incorporar tu sitio como un iframe, esto puede permitir que los atacantes invoquen acciones no deseadas por el usuario con clickjacking. Además, en algunos casos, los ataques de tipo Spectre les dan a los sitios web maliciosos la oportunidad de conocer el contenido de un documento incorporado.
X-Frame-Options indica si se debe permitir que un navegador renderice
una página en un <frame>, <iframe>, <embed> o <object>. Se recomienda que todos los documentos envíen este encabezado para indicar si permiten que otros documentos los incorporen.
Ejemplo de uso
X-Frame-Options: DENY
Usos recomendados
Todos los documentos que no estén diseñados para incorporarse deben usar el encabezado X-Frame-Options.
Protege tu sitio web para que no se incorpore en ningún otro sitio web.
Rechaza que otros documentos lo incorporen.
X-Frame-Options: DENYProtege tu sitio web para que no lo incorporen sitios web de origen cruzado.
Permitir que solo se incorporen documentos del mismo origen.
X-Frame-Options: SAMEORIGINNavegadores compatibles
Más información
Política de recursos de origen cruzado (CORP)
Un atacante puede incorporar recursos de otro origen, por ejemplo, de tu sitio, para obtener información sobre ellos mediante la explotación de filtraciones entre sitios basadas en la Web.
Cross-Origin-Resource-Policy mitiga este riesgo indicando el conjunto de
sitios web en los que se puede cargar. El encabezado toma uno de tres valores:
same-origin, same-site y cross-origin. Se recomienda que todos los recursos envíen este encabezado para indicar si permiten que otros sitios web los carguen.
Ejemplo de uso
Cross-Origin-Resource-Policy: same-origin
Usos recomendados
Se recomienda que todos los recursos se entreguen con uno de los siguientes tres encabezados.
Permite que se carguen recursos cross-origin
Se recomienda que los servicios similares a CDN apliquen cross-origin a los recursos
(ya que, por lo general, se cargan con páginas de origen cruzado), a menos que ya se entreguen
a través de CORS, que tiene un efecto similar.
Cross-Origin-Resource-Policy: cross-originLimita los recursos que se cargarán desde el same-origin
same-origin se debe aplicar a los recursos que se deben cargar solo
en páginas del mismo origen. Debes aplicar esto a los recursos que incluyan información sensible sobre el usuario o a las respuestas de una API que se deba llamar solo desde el mismo origen.
Ten en cuenta que los recursos con este encabezado se pueden cargar directamente, por ejemplo, navegando a la URL en una ventana nueva del navegador. La política de recursos de origen cruzado solo protege el recurso para que no lo incorporen otros sitios web.
Cross-Origin-Resource-Policy: same-originLimita los recursos que se cargarán desde el same-site
Se recomienda aplicar same-site a recursos similares a los anteriores,
pero que están destinados a ser cargados por otros subdominios de tu sitio.
Cross-Origin-Resource-Policy: same-siteNavegadores compatibles
Más información
Política de apertura de origen cruzado (COOP)
El sitio web de un atacante puede abrir otro sitio en una ventana emergente para obtener información sobre él mediante la explotación de filtraciones entre sitios basadas en la Web. En algunos casos, esto también puede permitir la explotación de ataques de canal lateral basados en Spectre.
El encabezado Cross-Origin-Opener-Policy proporciona una forma para que un documento se aísle
de las ventanas de origen cruzado que se abren a través de window.open() o un vínculo con
target="_blank" sin rel="noopener". Como resultado, cualquier abridor de origen cruzado
del documento no tendrá referencia a él y no podrá interactuar
con él.
Ejemplo de uso
Cross-Origin-Opener-Policy: same-origin-allow-popups
Usos recomendados
Aísla un documento de las ventanas de origen cruzado
Si configuras same-origin, el documento se aislará de las ventanas de documentos de origen cruzado.
Cross-Origin-Opener-Policy: same-originAislar un documento de ventanas de origen cruzado, pero permitir ventanas emergentes
La configuración same-origin-allow-popups permite que un documento conserve una referencia a
sus ventanas emergentes, a menos que establezcan COOP con same-origin o
same-origin-allow-popups. Esto significa que same-origin-allow-popups aún puede
proteger el documento para que no se haga referencia a él cuando se abra como una ventana emergente, pero
permitir que se comunique con sus propias ventanas emergentes.
Cross-Origin-Opener-Policy: same-origin-allow-popupsPermite que las ventanas de origen cruzado hagan referencia a un documento
unsafe-none es el valor predeterminado, pero puedes indicar de forma explícita que este
documento se puede abrir en una ventana de origen cruzado y conservar el acceso mutuo.
Cross-Origin-Opener-Policy: unsafe-noneInforma patrones incompatibles con COOP
Puedes recibir informes cuando la COOP impide las interacciones entre ventanas con la API de Reporting.
Cross-Origin-Opener-Policy: same-origin; report-to="coop"La COOP también admite un modo de solo informes para que puedas recibirlos sin bloquear la comunicación entre documentos de origen cruzado.
Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop"Navegadores compatibles
Más información
Uso compartido de recursos entre dominios (CORS)
A diferencia de otros elementos de este artículo, el uso compartido de recursos entre dominios (CORS) no es un encabezado, sino un mecanismo del navegador que solicita y permite el acceso a recursos de origen cruzado.
De forma predeterminada, los navegadores aplican la política del mismo origen para evitar que una página web acceda a recursos de origen cruzado. Por ejemplo, cuando se carga una imagen de origen cruzado, aunque se muestre visualmente en la página web, el código JavaScript de la página no tiene acceso a los datos de la imagen. El proveedor de recursos puede relajar las restricciones y permitir que otros sitios web lean el recurso habilitando CORS.
Ejemplo de uso
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Antes de analizar cómo configurar CORS, es útil comprender la distinción entre los tipos de solicitudes. Según los detalles de la solicitud, esta se clasificará como una solicitud simple o una solicitud de comprobación preliminar.
Criterios para una solicitud simple:
- El método es
GET,HEADoPOST. - Los encabezados personalizados solo incluyen
Accept,Accept-Language,Content-LanguageyContent-Type. - El
Content-Typeesapplication/x-www-form-urlencoded,multipart/form-dataotext/plain.
Todo lo demás se clasifica como una solicitud con comprobación preliminar. Para obtener más detalles, consulta Uso compartido de recursos de origen cruzado (CORS) - HTTP | MDN.
Usos recomendados
Solicitud simple
Cuando una solicitud cumple con los criterios de solicitud simple, el navegador envía una
solicitud de origen cruzado con un encabezado Origin que indica el origen de la
solicitud.
Ejemplo de encabezado de la solicitud
Get / HTTP/1.1 Origin: https://example.com
Encabezado de respuesta de ejemplo
Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://example.comindica que elhttps://example.compuede acceder al contenido de la respuesta. Los recursos que pueden leer cualquier sitio pueden establecer este encabezado en*, en cuyo caso el navegador solo requerirá que la solicitud se realice sin credenciales.Access-Control-Allow-Credentials: trueindica que las solicitudes que llevan credenciales (cookies) pueden cargar el recurso. De lo contrario, se rechazarán las solicitudes autenticadas, incluso si el origen de la solicitud está presente en el encabezadoAccess-Control-Allow-Origin.
Solicitudes preliminares
Una solicitud con verificación previa va precedida de una solicitud OPTIONS para comprobar si se permite el envío de la solicitud posterior.
Ejemplo de encabezado de la solicitud
OPTIONS / HTTP/1.1 Origin: https://example.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-PINGOTHER, Content-Type
Access-Control-Request-Method: POSTpermite que se realice la siguiente solicitud con el métodoPOST.Access-Control-Request-Headers: X-PINGOTHER, Content-Typepermite que el solicitante establezca los encabezados HTTPX-PINGOTHERyContent-Typeen la solicitud posterior.
Encabezados de respuesta de ejemplo
Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: X-PINGOTHER, Content-Type Access-Control-Max-Age: 86400
Access-Control-Allow-Methods: POST, GET, OPTIONSindica que se pueden realizar solicitudes posteriores con los métodosPOST,GETyOPTIONS.Access-Control-Allow-Headers: X-PINGOTHER, Content-Typeindica que las solicitudes posteriores pueden incluir los encabezadosX-PINGOTHERyContent-Type.Access-Control-Max-Age: 86400indica que el resultado de la solicitud preliminar se puede almacenar en caché durante 86,400 segundos.
Navegadores compatibles
Más información
Política de incorporaciones de origen cruzado (COEP)
Para reducir la capacidad de los ataques basados en Spectre de robar recursos de origen cruzado, las funciones como SharedArrayBuffer o performance.measureUserAgentSpecificMemory() están inhabilitadas de forma predeterminada.
Cross-Origin-Embedder-Policy: require-corp evita que los documentos y los trabajadores carguen recursos de origen cruzado, como imágenes, secuencias de comandos, hojas de estilo, iframes y otros, a menos que estos recursos habiliten de forma explícita la carga a través de encabezados CORS o CORP. La COEP se puede combinar conCross-Origin-Opener-Policy
para habilitar el aislamiento de origen cruzado en un documento.
Usa Cross-Origin-Embedder-Policy: require-corp cuando quieras habilitar el
aislamiento de origen cruzado para tu documento.
Ejemplo de uso
Cross-Origin-Embedder-Policy: require-corp
Ejemplos de uso
La COEP toma un solo valor de require-corp. Si envías este encabezado, puedes
indicarle al navegador que bloquee la carga de recursos que no se habiliten a través de
CORS o CORP.
Habilita el aislamiento de origen cruzado
Habilita el aislamiento de origen cruzado enviando Cross-Origin-Embedder-Policy: require-corp junto con Cross-Origin-Opener-Policy: same-origin.
Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Opener-Policy: same-origin
Informa recursos incompatibles con COEP
Puedes recibir informes de recursos bloqueados causados por la COEP con la API de Reporting.
Cross-Origin-Embedder-Policy: require-corp; report-to="coep"La COEP también admite el modo de solo informes para que puedas recibir informes sin bloquear la carga de recursos.
Cross-Origin-Embedder-Policy-Report-Only: require-corp; report-to="coep"Navegadores compatibles
Más información
HTTP con Seguridad de Transporte Estricta (HSTS)
La comunicación a través de una conexión HTTP simple no está encriptada, lo que hace que los datos transferidos sean accesibles para los espías a nivel de red.
El encabezado Strict-Transport-Security informa al navegador que nunca debe cargar
el sitio con HTTP y que, en su lugar, debe usar HTTPS. Una vez que se configura, el navegador usará
HTTPS en lugar de HTTP para acceder al dominio sin un redireccionamiento durante un período
definido en el encabezado.
Ejemplo de uso
Strict-Transport-Security: max-age=31536000
Usos recomendados
Todos los sitios web que realicen la transición de HTTP a HTTPS deben responder con un encabezado Strict-Transport-Security cuando se reciba una solicitud con HTTP.
Strict-Transport-Security: max-age=31536000Navegadores compatibles