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

Evite vazamentos de CSRF, XSSI e informações entre origens.

Muitos aplicativos da Web são vulneráveis a ataques cross-origin, como falsificação de solicitação entre sites (CSRF), inclusão de script entre sites (XSSI), ataques de temporização, vazamentos de informações cross-origin ou ataques de canal lateral de execução especulativa (Spectre).

Os cabeçalhos de solicitação Buscar metadados permitem implantar um mecanismo de defesa em profundidade robusto, uma política de isolamento de recursos, para proteger seu aplicativo contra esses ataques comuns entre origens.

É comum que os recursos expostos por um determinado aplicativo da Web sejam carregados apenas pelo próprio aplicativo, e não por outros sites. Nesses casos, a implantação de uma política de isolamento de recursos com base nos cabeçalhos de solicitação de busca de metadados 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 extração de metadados são compatíveis com todos os mecanismos de navegadores modernos.

Compatibilidade com navegadores

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Origem

Contexto

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

Outros ataques entre sites, como a inclusão de script entre sites (XSSI) ou vazamentos de informações entre origens, têm natureza semelhante ao CSRF e dependem do carregamento de recursos de um aplicativo 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 extração de metadados são um novo recurso de segurança da plataforma da Web desenvolvido para ajudar os servidores a se defender contra ataques entre origens. Ao fornecer informações sobre o contexto de uma solicitação HTTP em um conjunto de cabeçalhos Sec-Fetch-*, eles 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 aceitam ou rejeitam uma solicitação com base na forma como ela foi feita e no contexto em que será usada, o que possibilita responder apenas a solicitações legítimas feitas pelo próprio aplicativo.

Same-Origin
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
As solicitações entre sites maliciosas podem ser rejeitadas pelo servidor devido ao contexto adicional na solicitação HTTP fornecido pelos cabeçalhos Sec-Fetch-*. Uma imagem em https://evil.example que definiu o atributo src de um elemento img 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

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Origem

O 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 app (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 do usuário com o user agent (por exemplo, clicar em um marcador)
  • cross-site, se a solicitação foi enviada por outro site (por exemplo, evil.example)

Sec-Fetch-Mode

Compatibilidade com navegadores

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Origem

Sec-Fetch-Mode indica o modo da solicitação. Isso corresponde aproximadamente ao tipo da solicitação e permite distinguir as cargas de recursos das solicitações de navegação. Por exemplo, um destino de 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

  • Chrome: 80.
  • Edge: 80.
  • Firefox: 90.
  • Safari: 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 entre origens

As informações extras fornecidas por esses cabeçalhos de solicitação são bastante simples, mas o contexto adicional permite criar uma lógica de segurança poderosa no servidor, também chamada de 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 seus recursos sejam solicitados por sites externos. O bloqueio desse tráfego mitiga vulnerabilidades comuns de sites cruzados, como CSRF, XSSI, ataques de tempo e vazamentos de informações de origem cruzada. Essa política pode ser ativada para todos os endpoints do seu app e permite todas as solicitações de recursos provenientes do seu próprio app, bem como navegações diretas (por uma solicitação HTTP GET). Os endpoints que precisam ser carregados em um contexto entre sites (por exemplo, endpoints carregados usando o CORS) podem ser excluídos dessa lógica.

Etapa 1: permitir solicitações de navegadores que não enviam o Fetch Metadata

Como nem todos os navegadores oferecem suporte ao Fetch Metadata, é necessário permitir solicitações que não definem 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 navegador e no mesmo site

Todas as solicitações que não tiverem origem em um contexto entre origens (como evil.example) serão permitidas. Mais especificamente, são solicitações que:

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

Etapa 3: permitir a navegação e o iframing simples no nível superior

Para garantir que seu site ainda possa ser vinculado de outros sites, é necessário permitir a navegação simples (HTTP GET) de 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: desativar endpoints destinados a veicular tráfego entre sites (opcional)

Em alguns casos, o app pode fornecer recursos que devem ser carregados em vários sites. Esses recursos precisam ser isentos por caminho ou endpoint. Confira alguns exemplos de endpoints:

  • Endpoints que precisam ser acessados entre origens: se o aplicativo estiver exibindo endpoints com CORS ativado, é necessário desativá-los explicitamente do isolamento de recursos para garantir que as solicitações entre sites para esses endpoints ainda sejam possíveis.
  • Recursos públicos (por exemplo, imagens, estilos etc.): Qualquer recurso público e não autenticado que possa ser carregado em várias origens de outros sites também pode ser excluído.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

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

Qualquer outra solicitação entre sites será rejeitada por essa política de isolamento de recursos e, portanto, 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, permitindo 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

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 site e garantir que as restrições não afetem o tráfego legítimo.
  2. Corrija possíveis violações isentando endpoints legítimos de origem cruzada.
  3. Aplique a política descartando as solicitações que não estão em conformidade.

Como identificar e corrigir violações da política

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

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

Como aplicar uma política de isolamento de recursos

Depois de verificar que a política não afeta o tráfego legítimo de produção, você pode aplicar restrições, garantindo que outros sites não solicitem seus recursos e protegendo seus usuários contra ataques entre sites.

Leitura adicional