Proteja seus recursos contra ataques na Web com a busca de metadados

Evitar vazamentos de informações de origem cruzada, CSRF e XSSI.

Por que é importante isolar seus recursos da Web?

Muitos aplicativos da Web são vulneráveis a ataques de origem cruzada, como falsificação de solicitações entre sites (CSRF, na sigla em inglês), inclusão de scripts entre sites (XSSI, na sigla em inglês), ataques de tempo, vazamentos de informações de origem cruzada ou ataques de canal lateral de execução especulativa (Spectre).

Os cabeçalhos de solicitação de Buscar metadados permitem que você implante um mecanismo forte de defesa em profundidade, uma Política de Isolamento de Recursos, para proteger seu aplicativo contra esses ataques comuns de origem cruzada.

É comum que recursos expostos por um determinado aplicativo da Web sejam carregados apenas pelo próprio aplicativo e não por outros sites. Nesses casos, implantar uma política de isolamento de recursos com base em cabeçalhos de solicitação de metadados de busca exige pouco esforço e, ao mesmo tempo, protege o aplicativo contra ataques entre sites.

Compatibilidade com navegadores

Os cabeçalhos de solicitação de metadados de busca são compatíveis com todos os mecanismos de navegador modernos.

Compatibilidade com navegadores

  • 76
  • 79
  • 90
  • 16.4

Origem

Contexto

Muitos ataques entre sites são possíveis porque a Web é aberta por padrão e o servidor de aplicativos não consegue se proteger facilmente contra comunicações originadas de aplicativos externos. Um ataque de origem cruzada típico é a falsificação de solicitações entre sites (CSRF, na sigla em inglês), em que um atacante atrai um usuário para um site que ele controla e, em seguida, envia um formulário ao servidor no qual o usuário está conectado. Como o servidor não consegue determinar se a solicitação foi originada de outro domínio (entre sites) e o navegador anexa automaticamente cookies a solicitações entre sites, o servidor executará a ação solicitada pelo invasor em nome do usuário.

Outros ataques entre sites, como inclusão de script em vários locais (XSSI) ou vazamentos de informações de origem cruzada, são de natureza semelhante ao CSRF e dependem do carregamento de recursos de um aplicativo da vítima em um documento controlado pelo invasor e do vazamento de informações sobre os aplicativos da vítima. Como os aplicativos não conseguem distinguir facilmente as solicitações confiáveis das não confiáveis, eles não podem descartar o tráfego malicioso entre sites.

Introdução à busca de metadados

Os cabeçalhos de solicitação de busca de metadados são um novo recurso de segurança de plataforma da Web desenvolvido para ajudar os servidores a se defenderem contra ataques de origem cruzada. Ao fornecer informações sobre o contexto de uma solicitação HTTP em um conjunto de cabeçalhos Sec-Fetch-*, elas permitem que o servidor que responde aplique políticas de segurança antes de processar a solicitação. Isso permite que os desenvolvedores decidam se querem aceitar ou recusar uma solicitação com base na forma como ela foi feita e no contexto em que será usada, possibilitando responder apenas a solicitações legítimas feitas pelos próprios aplicativos.

Mesma origem
As solicitações originadas de sites veiculados pelo seu próprio servidor (mesma origem) vão continuar funcionando. Uma solicitação de busca de https://site.example para o recurso https://site.example/foo.json em JavaScript faz com que o navegador envie o cabeçalho de solicitação HTTP "Sec Fetch-Site: same-origin".
Entre sites
Solicitações maliciosas entre sites podem ser rejeitadas pelo servidor devido ao contexto extra na solicitação HTTP fornecida pelos cabeçalhos Sec-Fetch-*. Uma imagem em https://evil.example com o atributo src de um elemento img definido como "https://site.example/foo.json" faz com que o navegador envie o cabeçalho de solicitação HTTP "Sec-Fetch-Site: cross-site".

Sec-Fetch-Site

Compatibilidade com navegadores

  • 76
  • 79
  • 90
  • 16.4

Origem

Sec-Fetch-Site informa ao servidor qual site enviou a solicitação. O navegador define esse valor como um dos seguintes:

  • same-origin, se a solicitação foi feita pelo seu próprio aplicativo (por exemplo, site.example)
  • same-site, se a solicitação foi feita por um subdomínio do seu site (por exemplo, bar.site.example)
  • none, se a solicitação foi causada explicitamente pela interação de um usuário com o user agent (por exemplo, clicar em um favorito)
  • cross-site, se a solicitação foi enviada por outro site (por exemplo, evil.example)

Sec-Fetch-Mode

Compatibilidade com navegadores

  • 76
  • 79
  • 90
  • 16.4

Origem

Sec-Fetch-Mode indica o modo da solicitação. Isso corresponde aproximadamente ao tipo da solicitação e permite distinguir carregamentos de recursos das solicitações de navegação. Por exemplo, um destino navigate indica uma solicitação de navegação de nível superior, enquanto no-cors indica solicitações de recursos, como o carregamento de uma imagem.

Sec-Fetch-Dest

Compatibilidade com navegadores

  • 80
  • 80
  • 90
  • 16.4

Origem

Sec-Fetch-Dest expõe o destino de uma solicitação (por exemplo, se uma tag script ou img fez com que um recurso fosse solicitado pelo navegador).

Como usar o Fetch Metadata para se proteger contra ataques de origem cruzada

As informações extras que esses cabeçalhos de solicitação fornecem são bastante simples, mas o contexto adicional permite que você construa uma lógica de segurança poderosa no lado do servidor, também conhecida como política de isolamento de recursos, com apenas algumas linhas de código.

Como implementar uma política de isolamento de recursos

Uma política de isolamento de recursos impede que recursos sejam solicitados por sites externos. O bloqueio desse tipo de tráfego reduz as vulnerabilidades comuns da Web entre sites, como CSRF, XSSI, ataques de velocidade e vazamentos de informações de origem cruzada. Ela pode ser ativada para todos os endpoints do seu aplicativo e vai permitir todas as solicitações de recursos provenientes do seu aplicativo, além de navegações diretas (por uma solicitação HTTP GET). Os endpoints que devem ser carregados em um contexto entre sites (por exemplo, endpoints carregados usando CORS) podem ser desativados nessa lógica.

Etapa 1: permitir solicitações de navegadores que não enviam metadados de busca

Como nem todos os navegadores são compatíveis com a busca de metadados, é necessário permitir solicitações que não definam cabeçalhos Sec-Fetch-*, verificando a presença de sec-fetch-site.

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

Etapa 2: permitir solicitações iniciadas pelo mesmo site e pelo navegador

Quaisquer solicitações que não se originem de um contexto de origem cruzada (como evil.example) serão permitidas. Especificamente, essas são as solicitações que:

  • Ter origem no seu próprio aplicativo, por exemplo, uma solicitação de mesma origem em que as solicitações site.example/foo.json do site.example sempre serão permitidas.
  • têm origem nos seus subdomínios;
  • São causadas explicitamente pela interação de um usuário com o user agent (por exemplo, navegação direta ou clique em um favorito etc.).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

Etapa 3: permita a navegação simples de nível superior e o iframe

Para garantir que seu site ainda possa ser vinculado a outros sites, permita a navegação simples (HTTP GET) no nível superior.

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

Etapa 4: desative os endpoints que atendem ao tráfego entre sites (opcional)

Em alguns casos, o aplicativo pode fornecer recursos para carregamento entre sites. Esses recursos precisam ser isentos por caminho ou por endpoint. Exemplos desses endpoints:

  • Endpoints para acesso de origem cruzada: se o aplicativo disponibilizar endpoints com CORS ativados, será necessário desativar explicitamente o isolamento de recursos para garantir que as solicitações entre sites ainda sejam possíveis.
  • Recursos públicos (por exemplo, imagens, estilos etc.): Recursos públicos e não autenticados que precisem ser carregados de origem cruzada de outros sites também podem ser isentos.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

Etapa 5: rejeitar todas as outras solicitações entre sites e não de navegação

Qualquer outra solicitação entre sites será rejeitada por esta Política de isolamento de recursos e vai proteger seu aplicativo contra ataques comuns entre sites.

Exemplo:o código a seguir demonstra uma implementação completa de uma política de isolamento de recursos robusta no servidor ou como um middleware para negar solicitações de recursos entre sites potencialmente maliciosas, ao mesmo tempo em que permite solicitações de navegação 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

Como implantar uma política de isolamento de recursos

  1. Instale um módulo, como o snippet de código acima, para registrar e monitorar o comportamento do seu site e garantir que as restrições não afetem um tráfego legítimo.
  2. Para corrigir possíveis violações, isente endpoints legítimos de origem cruzada.
  3. Aplicar a política descartando solicitações não compatíveis.

Identificar e corrigir violações da política

Recomendamos que você teste sua política sem efeitos colaterais. Para isso, ative-a primeiro no modo de relatório no código no lado do servidor. Como alternativa, é possível implementar essa lógica em um middleware ou em um proxy reverso, que registra todas as violações que sua política pode produzir quando aplicada ao tráfego de produção.

Com base na nossa experiência de implementação de uma política de isolamento de recursos de metadados de busca no Google, a maioria dos aplicativos é compatível por padrão com essa política e raramente requer a isenção de endpoints para permitir tráfego entre sites.

Como aplicar uma política de isolamento de recursos

Depois de confirmar que sua política não afeta o tráfego de produção legítimo, você poderá aplicar as restrições, garantindo que outros sites não possam solicitar seus recursos e protegendo os usuários contra ataques entre sites.

Leia mais