← Todas as verificações
SegurançaSeveridade típica: Alto

Scanner de CORS permissivo

Verifica se a tua política CORS reflete qualquer origem com credenciais, expondo os dados dos teus utilizadores.

O que verifica

Este scanner verifica a tua política CORS para ver se aceita pedidos de qualquer origem e ao mesmo tempo permite o envio de credenciais. Essa combinação é a configuração de CORS mais perigosa possível. Só olha para como respondes a pedidos de outros domínios, sem aceder a nenhum dado.

Porque importa

Se refletires qualquer origem com credenciais, um site malicioso pode fazer pedidos à tua API usando a sessão de um utilizador com login e ler a resposta. Isso expõe dados privados dos teus utilizadores a terceiros. Costuma acontecer por copiar uma configuração aberta de exemplos ou tutoriais.

Como se corrige

Substitui a origem com curinga por uma lista explícita de domínios de confiança que realmente precisam de aceder à tua API. Se não precisas de enviar credenciais entre domínios, desativa essa opção. Revê a configuração CORS do teu backend ou framework e evita refletir automaticamente a origem que chega.

Como funciona esta verificação

O Scanaris volta a pedir a tua página principal com um cabeçalho Origin de um domínio inventado, como faria o navegador se outro site tentasse chamar-te, e vê o que o teu servidor responde. Se Access-Control-Allow-Origin devolver essa mesma origem e além disso Access-Control-Allow-Credentials for true, abre um achado de severidade alta: o teu servidor reflete qualquer origem com credenciais. Se responder com o wildcard * juntamente com credenciais, abre um de severidade baixa: os navegadores rejeitam essa combinação, mas denuncia uma configuração feita às cegas. Só se testa o URL analisado; se a tua API vive noutra rota ou domínio, testa-a com o comando mais abaixo.

O que um atacante faz com isto

Monta uma página em qualquer domínio com um fetch à tua API a usar credentials: 'include'. Quando um dos teus utilizadores, com sessão aberta, visita essa página, o navegador anexa os cookies dele, o teu servidor responde com os dados do utilizador e, como a política CORS o permite, a página do atacante lê-os. Perfil, encomendas, mensagens, o que a API devolver. O utilizador não vê nada: acontece em segundo plano.

Porque acontece

O CORS existe para que o navegador bloqueie por defeito as leituras entre domínios. Quando uma chamada falha em desenvolvimento (a app numa porta, a API noutra), a solução rápida que os tutoriais e as ferramentas de IA sugerem é "permitir todas as origens", e para os cookies funcionarem acrescenta-se "com credenciais". Em produção isso significa que a proteção ficou desativada. Mais detalhe em CORS mal configurado: a falha silenciosa que expõe os teus utilizadores.

Como corrigir

  • Lista explícita de origens. Só os domínios que de facto chamam a tua API a partir do navegador. Em Express: cors({ origin: ['https://app.oteudominio.com'], credentials: true }). Em Next.js, no Route Handler, compara o Origin com a tua lista antes de o devolver. Em Nuxt, com routeRules e a opção cors ou um middleware de servidor.
  • Nunca reflitas a origem. Copiar o valor de Origin para a resposta "porque assim funciona tudo" é exatamente o erro que o check mede.
  • Se não precisas de cookies entre domínios, tira o Access-Control-Allow-Credentials. Sem credenciais, um * numa API pública só de leitura é aceitável.
  • Acrescenta Vary: Origin quando a resposta depender da origem, para que nenhuma cache sirva a um domínio a resposta de outro.
  • Cookies com SameSite=Lax ou Strict como segunda barreira: mesmo que o CORS falhasse, o navegador não os enviaria a partir de outro site.

Confirma que está corrigido

curl -sI -H "Origin: https://evil.example" https://oteudominio.com/api/me | grep -i "access-control"

O correto é que não apareça Access-Control-Allow-Origin para essa origem, ou que apareça com o teu domínio e não com evil.example. Testa também com o teu próprio domínio no Origin para confirmar que a tua app continua a funcionar.

Perguntas frequentes

A minha API é pública e sem login. É um problema?

Não, se não houver cookies nem cabeçalhos de autorização. Access-Control-Allow-Origin: * sem credenciais é a configuração correta para uma API aberta.

Tenho vários subdomínios que chamam a API.

Lista-os todos ou valida o Origin contra um padrão estrito do teu domínio raiz. Nunca valides com "contém oteudominio.com": oteudominio.com.evil.example cumpre isso.

E o localhost para desenvolver?

Acrescenta-o só no ambiente de desenvolvimento, com uma variável de ambiente. Um http://localhost:3000 na lista de produção é uma origem que qualquer programa no computador do utilizador pode usar.

Verifica-o no teu site

Analisa o teu site grátis e vê se esta e outras 44 verificações passam, com um fix prompt por cada problema.

Analisar o meu site grátis

Do blog

Verificações relacionadas