Protege tus recursos contra ataques web con la función para recuperar metadatos

Evita las filtraciones de información de CSRF, XSSI y de origen cruzado.

¿Por qué es importante aislar tus recursos web?

Muchas aplicaciones web son vulnerables a ataques de origen cruzado, como la falsificación de solicitudes entre sitios (CSRF), la inclusión de secuencias de comandos entre sitios (XSSI), los ataques de sincronización, las filtraciones de información de origen cruzado o los ataques de canal lateral de ejecución especulativa (Spectre).

Los encabezados de las solicitudes de recuperación de metadatos te permiten implementar un mecanismo sólido de defensa en profundidad (una política de aislamiento de recursos) para proteger tu aplicación contra estos ataques comunes de origen cruzado.

Es común que los recursos expuestos por una aplicación web determinada solo se carguen por la aplicación en sí y no por otros sitios web. En tales casos, implementar una política de aislamiento de recursos basada en encabezados de solicitudes para recuperar metadatos requiere poco esfuerzo y, al mismo tiempo, protege la aplicación de ataques entre sitios.

Compatibilidad del navegador

Los encabezados de las solicitudes de Recuperación de metadatos son compatibles con todos los motores de navegador modernos.

Navegadores compatibles

  • 76
  • 79
  • 90
  • 16.4

Origen

Información general

Muchos ataques entre sitios son posibles porque la Web está abierta de forma predeterminada y tu servidor de aplicaciones no puede protegerse fácilmente de las comunicaciones que se originan en aplicaciones externas. Un ataque típico de origen cruzado es la falsificación de solicitudes entre sitios (CSRF) en la que un atacante engaña a un usuario a un sitio que controla y, luego, envía un formulario al servidor al que accedió el usuario. Dado que el servidor no puede determinar si la solicitud se originó desde otro dominio (entre sitios) y el navegador adjunta automáticamente cookies a las solicitudes entre sitios, el servidor ejecutará la acción solicitada por el atacante en nombre del usuario.

Otros ataques entre sitios, como la inclusión de secuencias de comandos entre sitios (XSSI) o las filtraciones de información de origen cruzado, son de naturaleza similar a los CSRF y dependen de la carga de recursos desde una aplicación víctima en un documento controlado por el atacante y la filtración de información sobre las aplicaciones víctimas. Dado que las aplicaciones no pueden distinguir fácilmente las solicitudes confiables de las no confiables, no pueden descartar el tráfico malicioso entre sitios.

Presentamos la función Recuperar metadatos

Los encabezados de las solicitudes para recuperar metadatos son una nueva función de seguridad para plataformas web diseñada para ayudar a los servidores a defenderse de los ataques de origen cruzado. Cuando se proporciona información sobre el contexto de una solicitud HTTP en un conjunto de encabezados Sec-Fetch-*, permiten que el servidor que responde aplique políticas de seguridad antes de procesar la solicitud. Esto permite a los desarrolladores decidir si aceptar o rechazar una solicitud en función de la forma en que se realizó y el contexto en el que se utilizará, lo que posibilita responder solo a las solicitudes legítimas realizadas por su propia aplicación.

Mismo origen
Las solicitudes que se originan en sitios entregados por tu propio servidor (mismo origen) seguirán funcionando. Una solicitud de recuperación de https://site.example para el recurso https://site.example/foo.json en JavaScript hace que el navegador envíe el encabezado de la solicitud HTTP "Sec Fetch-Site: same-origin".
Varios sitios
El servidor puede rechazar las solicitudes maliciosas entre sitios debido al contexto adicional en la solicitud HTTP que proporcionan los encabezados Sec-Fetch-*. Una imagen en https://evil.example que estableció el atributo src de un elemento img en "https://site.example/foo.json" hace que el navegador envíe el encabezado de la solicitud HTTP "Sec-Fetch-Site: cross-site".

Sec-Fetch-Site

Navegadores compatibles

  • 76
  • 79
  • 90
  • 16.4

Origen

Sec-Fetch-Site le indica al servidor qué sitio envió la solicitud. El navegador establece este valor en una de las siguientes opciones:

  • same-origin, si la solicitud la realizó tu propia aplicación (p.ej., site.example)
  • same-site, si la solicitud la realizó un subdominio de tu sitio (p.ej., bar.site.example)
  • none, si la solicitud se debe explícitamente a la interacción de un usuario con el usuario-agente (p.ej., al hacer clic en un favorito)
  • cross-site, si la solicitud la envió otro sitio web (p.ej., evil.example)

Sec-Fetch-Mode

Navegadores compatibles

  • 76
  • 79
  • 90
  • 16.4

Origen

Sec-Fetch-Mode indica el modo de la solicitud. Esto corresponde, aproximadamente, al tipo de solicitud y te permite distinguir las cargas de recursos de las solicitudes de navegación. Por ejemplo, un destino de navigate indica una solicitud de navegación de nivel superior, mientras que no-cors indica solicitudes de recursos, como cargar una imagen.

Sec-Fetch-Dest

Navegadores compatibles

  • 80
  • 80
  • 90
  • 16.4

Origen

Sec-Fetch-Dest expone el destino de una solicitud (p.ej., si una etiqueta script o img hizo que el navegador solicite un recurso).

Cómo usar la función Obtener metadatos para protegerte de ataques de origen cruzado

La información adicional que proporcionan estos encabezados de solicitud es bastante simple, pero el contexto adicional te permite compilar una lógica de seguridad potente del lado del servidor, también conocida como política de aislamiento de recursos, con solo unas pocas líneas de código.

Implementar una política de aislamiento de recursos

Una política de aislamiento de recursos evita que sitios web externos soliciten tus recursos. El bloqueo de ese tráfico mitiga las vulnerabilidades comunes entre sitios, como CSRF, XSSI, ataques de sincronización y filtraciones de información de origen cruzado. Esta política se puede habilitar para todos los extremos de tu aplicación y permitirá todas las solicitudes de recursos que provengan de tu propia aplicación, así como las navegaciones directas (a través de una solicitud HTTP GET). Los extremos que se suponen que se deben cargar en un contexto de varios sitios (p.ej., extremos cargados con CORS) pueden inhabilitarse de esta lógica.

Paso 1: Permite las solicitudes de navegadores que no envíen metadatos de recuperación

Dado que no todos los navegadores admiten la recuperación de metadatos, debes permitir las solicitudes que no establecen encabezados Sec-Fetch-*. Para ello, verifica la presencia de sec-fetch-site.

if not req['sec-fetch-site']:
  return True  # Allow this request

Paso 2: Permite las solicitudes en el mismo sitio o iniciadas por el navegador

Se permitirán todas las solicitudes que no provengan de un contexto de origen cruzado (como evil.example). En particular, estas son solicitudes que hacen lo siguiente:

  • Origina desde tu propia aplicación (p.ej., una solicitud del mismo origen en la que site.example solicita site.example/foo.json siempre se permitirá).
  • Se origina en tus subdominios.
  • Se producen explícitamente por la interacción de un usuario con el usuario-agente (p.ej., la navegación directa o el clic en un favorito, etc.).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

Paso 3: Permite la navegación y el iframe y la navegación de nivel superior simples

Para asegurarte de que tu sitio aún pueda vincularse desde otros sitios, debes permitir la navegación simple de nivel superior (HTTP GET).

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

Paso 4: Inhabilita los extremos diseñados para entregar tráfico entre sitios (opcional)

En algunos casos, tu aplicación puede proporcionar recursos diseñados para cargarse en varios sitios. Estos recursos se deben excluir por ruta o por extremo. Algunos ejemplos de estos endpoints son los siguientes:

  • Extremos diseñados para ser de origen cruzado: Si tu aplicación entrega extremos que están habilitados para CORS, debes inhabilitarlos de forma explícita del aislamiento de recursos para garantizar que aún sean posibles las solicitudes entre sitios a estos extremos.
  • Recursos públicos (p.ej., imágenes, estilos, etc.): También se pueden excluir los recursos públicos y no autenticados de origen cruzado que se puedan cargar desde otros sitios.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

Paso 5: Rechaza todas las demás solicitudes que sean entre sitios y no de navegación

Esta Política de aislamiento de recursos rechazará cualquier otra solicitud entre sitios y, por lo tanto, protegerá tu aplicación de ataques comunes entre sitios.

Ejemplo: En el siguiente código, se muestra la implementación completa de una política de aislamiento de recursos sólida en el servidor o como middleware para denegar solicitudes de recursos entre sitios potencialmente maliciosas y, al mismo tiempo, permitir solicitudes de navegación simples:

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

Implementar una política de aislamiento de recursos

  1. Instala un módulo como el fragmento de código que se incluye más arriba para registrar y supervisar el comportamiento de tu sitio, y asegúrate de que las restricciones no afecten el tráfico legítimo.
  2. Para corregir los posibles incumplimientos, excluye los extremos de origen cruzado legítimos.
  3. Rechaza las solicitudes que no cumplan con la política para aplicar la política.

Identificación y solución de incumplimientos de política

Te recomendamos que pruebes tu política de una manera sin efectos secundarios. Para ello, primero debes habilitarla en el modo de informes en tu código del servidor. Como alternativa, puedes implementar esta lógica en middleware o en un proxy inverso que registre cualquier incumplimiento que tu política pueda producir cuando se aplique al tráfico de producción.

A partir de nuestra experiencia con el lanzamiento de una Política de aislamiento de recursos de recuperación de metadatos en Google, la mayoría de las aplicaciones son compatibles de forma predeterminada con dicha política y rara vez requieren la exención de extremos para permitir el tráfico entre sitios.

Aplica una política de aislamiento de recursos

Después de verificar que tu política no afecta el tráfico de producción legítimo, tendrás todo listo para aplicar restricciones, lo que garantiza que otros sitios no puedan solicitar tus recursos y protege a tus usuarios de ataques entre sitios.

Lecturas adicionales