Pular para o conteúdo
Segurança Web11 min de leituraAtualizado em Por Equipe GUARDIASEC

CORS em aplicações web: riscos comuns e configuração segura

CORS é mal compreendido e mal configurado. Veja o que ele realmente faz e como evitar liberar demais.

CORS é um dos temas mais mal compreendidos em segurança web. Muita gente acha que ele protege a API, quando na verdade é um mecanismo do navegador que controla quais origens podem ler respostas de requisições feitas a partir de outra origem. Configurações erradas de CORS são comuns: liberar qualquer origem por conveniência, refletir a origem da requisição sem validar ou combinar origem ampla com credenciais, abrindo brechas reais.

Este guia explica CORS de forma clara e defensiva: o que ele faz e o que não faz, como funciona o preflight, os erros mais comuns, a relação com CSRF e como configurar de maneira segura. O foco é entender o mecanismo para não enfraquecê-lo sem perceber.

O que CORS faz e o que não faz

CORS é aplicado pelo navegador. Ele decide se o JavaScript de uma origem pode ler a resposta de uma requisição a outra origem, com base nos cabeçalhos que o servidor retorna, como Access-Control-Allow-Origin. CORS não é autenticação nem autorização e não protege contra requisições feitas fora do navegador, como por ferramentas de linha de comando. Ele controla leitura entre origens no contexto do navegador, nada além.

Isso significa que CORS não substitui controle de acesso no servidor. A API ainda precisa autenticar e autorizar cada requisição. Confiar no CORS como barreira de segurança do backend é um equívoco que deixa a API exposta a clientes que não são navegadores, já que qualquer cliente que ignore a política do navegador alcança a API do mesmo jeito.

Preflight e cabeçalhos em detalhe

Nem toda requisição entre origens dispara a mesma verificação. Requisições simples, como um GET sem cabeçalhos incomuns, são enviadas direto, e o navegador apenas decide se o JavaScript pode ler a resposta. Requisições que usam métodos como PUT e DELETE, ou cabeçalhos personalizados, disparam antes um preflight: uma requisição OPTIONS que pergunta ao servidor se aquele método e aqueles cabeçalhos são permitidos, por meio de Access-Control-Request-Method e Access-Control-Request-Headers.

Um detalhe de segurança frequentemente ignorado: o curinga em Access-Control-Allow-Origin não pode ser combinado com credenciais. Quando a resposta inclui Access-Control-Allow-Credentials com valor verdadeiro, o navegador exige que a origem seja explícita, não o curinga. Por isso muitos servidores refletem a origem recebida para contornar essa regra, o que reintroduz o risco. Ao usar origem dinâmica, adicione Vary com o valor Origin para não envenenar caches com a resposta de uma origem errada.

Comparação: configuração perigosa e configuração segura
// perigoso: origem refletida sem validar, com credenciais
Access-Control-Allow-Origin: <origem-refletida>
Access-Control-Allow-Credentials: true

// seguro: origem validada contra uma lista antes de responder
Access-Control-Allow-Origin: https://app.seu-dominio
Vary: Origin
Access-Control-Allow-Credentials: true

Erros comuns e impacto

O erro mais frequente é liberar qualquer origem com um curinga. Pior ainda é refletir dinamicamente a origem da requisição de volta no cabeçalho sem validar, o que efetivamente permite qualquer site. Quando isso se combina com permitir credenciais, uma página maliciosa pode fazer requisições autenticadas em nome do usuário e ler as respostas, levando a vazamento de dados.

Uma variante sutil é a validação de origem por comparação frouxa. Verificar apenas se a origem termina com o seu domínio deixa passar um domínio de atacante que contenha o seu nome como sufixo, e verificar apenas se ela contém o seu domínio é ainda pior. A comparação precisa ser exata contra uma lista de origens conhecidas. Cuidado também com o valor de origem nulo, que aparece em alguns contextos e não deve ser tratado como confiável.

  • Não liberar qualquer origem por padrão
  • Não refletir a origem da requisição sem validar contra uma lista exata
  • Não usar comparação por sufixo ou por conteúdo ao validar origem
  • Não tratar o valor de origem nulo como confiável
  • Ter cuidado redobrado ao permitir credenciais entre origens
  • Restringir métodos e cabeçalhos permitidos ao necessário
  • Lembrar que CORS não substitui autenticação no servidor

CORS não é a defesa contra CSRF

É comum confundir CORS com proteção contra CSRF, mas eles resolvem problemas diferentes. CORS controla se o JavaScript pode ler a resposta de uma requisição entre origens. CSRF explora o fato de que o navegador envia cookies automaticamente, e muitas requisições, como as simples ou o envio de formulários, chegam ao servidor e produzem efeito mesmo que o atacante nunca leia a resposta. Ou seja, uma política de CORS restrita não impede, por si só, que uma requisição forjada seja processada.

A defesa contra CSRF vem de outros controles: cookies com o atributo SameSite, tokens anti-CSRF em requisições que alteram estado e verificação de origem no servidor para operações sensíveis. Trate CORS e CSRF como camadas distintas, cada uma cobrindo o que a outra não cobre.

Configuração segura e testes

A configuração segura parte de uma lista de origens confiáveis, validando a origem da requisição por comparação exata contra essa lista antes de respondê-la. Permita apenas os métodos e cabeçalhos que a aplicação usa, e seja especialmente conservador ao habilitar credenciais. Diferencie APIs públicas sem credenciais, onde um curinga pode ser aceitável, de APIs autenticadas, onde a origem precisa ser explícita e validada.

Teste o comportamento de forma defensiva, verificando como a API responde a uma origem não autorizada, a uma origem parecida com a legítima mas diferente e ao valor de origem nulo, sempre nos seus próprios sistemas, sem atacar terceiros. Reavalie a configuração sempre que adicionar um novo cliente ou integração, porque cada nova origem confiável é uma decisão de segurança.

Checklist prático

  • Tratar CORS como controle de navegador, não de backend
  • Manter autenticação e autorização no servidor independentemente do CORS
  • Validar a origem por comparação exata contra uma lista de origens confiáveis
  • Não refletir a origem sem validação e não usar comparação por sufixo
  • Adicionar Vary com Origin quando a origem for dinâmica
  • Evitar liberar qualquer origem por padrão
  • Ter cautela ao permitir credenciais entre origens
  • Restringir métodos e cabeçalhos ao necessário
  • Tratar CSRF com SameSite e tokens, não com CORS
  • Diferenciar configuração de APIs públicas e autenticadas
  • Testar resposta a origens não autorizadas, parecidas e ao valor nulo
  • Revisar a configuração ao adicionar novos clientes

Boas práticas

  • Entenda que CORS protege o navegador, não a API
  • Use lista de origens confiáveis com comparação exata em vez de curinga
  • Seja conservador ao combinar origem e credenciais
  • Mantenha controle de acesso real no servidor
  • Defenda CSRF com controles próprios, sem contar com CORS
  • Restrinja métodos e cabeçalhos ao mínimo
  • Revise CORS sempre que a integração mudar

Erros comuns

  • Liberar qualquer origem com curinga

    Qualquer site pode ler respostas no navegador do usuário.

  • Refletir a origem da requisição sem validar

    Equivale a permitir qualquer origem, de forma disfarçada.

  • Validar origem por sufixo ou por conteúdo

    Um domínio de atacante com o seu nome como sufixo passa na verificação.

  • Origem ampla combinada com credenciais

    Página maliciosa faz requisições autenticadas e lê dados do usuário.

  • Confiar no CORS para conter CSRF

    Requisições forjadas ainda são processadas, mesmo sem leitura da resposta.

  • Tratar CORS como segurança do backend

    A API fica exposta a clientes que não são navegadores.

Quando procurar apoio especializado

Avaliar CORS junto da autenticação e da autorização da aplicação é parte dos serviços de Segurança de Aplicações e de Pentest da GUARDIASEC, que testam o comportamento real da API e identificam configurações que ampliam risco.

Perguntas frequentes

CORS protege a minha API?

Não diretamente. CORS é um mecanismo do navegador que controla quais origens podem ler respostas entre origens; ele não autentica nem autoriza, e não afeta requisições feitas fora do navegador. A API ainda precisa de controle de acesso próprio no servidor. CORS bem configurado evita abuso a partir de páginas de terceiros, mas não substitui autenticação.

Posso usar curinga em Access-Control-Allow-Origin?

É arriscado e, combinado com credenciais, nem funciona: o navegador não aceita curinga junto de Access-Control-Allow-Credentials verdadeiro. Liberar qualquer origem permite que sites de terceiros leiam respostas no navegador do usuário. O recomendado é validar a origem por comparação exata contra uma lista de origens confiáveis. Curinga pode ser aceitável apenas para APIs verdadeiramente públicas e sem credenciais.

Refletir a origem da requisição é seguro?

Não, se feito sem validação. Refletir dinamicamente a origem recebida de volta no cabeçalho equivale a permitir qualquer origem, só que de forma disfarçada. O correto é comparar a origem por igualdade exata com uma lista de permitidas e só então retorná-la, adicionando Vary com Origin para não envenenar caches. Refletir sem validar é um dos erros de CORS mais comuns e mais explorados.

Validar se a origem termina com o meu domínio é suficiente?

Não. A comparação por sufixo deixa passar domínios de atacante que contenham o seu nome como final, e a comparação por conteúdo é ainda mais frouxa. A validação precisa ser por igualdade exata contra uma lista de origens conhecidas, incluindo o esquema e a porta quando relevantes. Cuidado também com o valor de origem nulo, que não deve ser tratado como confiável.

CORS protege contra CSRF?

Não. CSRF explora o envio automático de cookies pelo navegador, e muitas requisições produzem efeito no servidor mesmo que o atacante nunca leia a resposta, que é o que o CORS controla. A defesa contra CSRF vem de cookies com atributo SameSite, tokens anti-CSRF e verificação de origem no servidor para operações sensíveis. São camadas distintas e ambas necessárias.

CORS e CSP são a mesma coisa?

Não. CORS controla quais origens podem ler respostas de requisições entre origens. CSP, Content Security Policy, controla de onde o navegador pode carregar recursos como scripts e estilos, ajudando contra XSS. São mecanismos diferentes e complementares: um cuida de acesso entre origens, o outro de carregamento de conteúdo na página.

Próximo passo

Vamos avaliar os riscos do seu ambiente?

Conte seu cenário e definimos juntos o escopo certo. O objetivo é reduzir caminhos prováveis de ataque e elevar a maturidade de segurança, sem promessas absolutas.