Glossário

O que é CORS — como funciona e o que uma configuração incorreta expõe

O CORS controla se o JavaScript de outra origem lê as respostas da sua API. Como um erro expõe dados de usuários logados e como configurar com segurança.

Publicado 2026-06-11 Atualizado 2026-10-06 7 min de leitura
Nesta página

Uma API que funciona depois que você adiciona Access-Control-Allow-Origin não é necessariamente segura. O CORS não é algo que você adiciona uma vez e esquece; o que importa é estreitar quem você permite. Veja como ele funciona e como configurá-lo com segurança (sem passos de ataque).

Primeiro, como funciona

Os navegadores aplicam uma política de mesma origem: o JS de outra origem não pode ler livremente as respostas de outro site. O CORS existe para abrir essa exceção apenas às partes que o servidor permite explicitamente.

Uma origem é a combinação de esquema (https), nome de host e porta. https://example.com e https://api.example.com têm hosts diferentes, então são origens diferentes; http://example.com e https://example.com diferem no esquema, então também são diferentes.

Cabeçalho de respostaSignificado
Access-Control-Allow-OriginQuais origens podem ler a resposta
Access-Control-Allow-CredentialsSe requisições com credenciais (cookies) são permitidas
Access-Control-Allow-Methods / -HeadersQuais métodos/cabeçalhos HTTP são permitidos

O ponto: o CORS está do lado do "afrouxar a restrição". Afrouxe-o errado e dados que não deveriam ser legíveis se tornam legíveis por terceiros.

Mais um detalhe importante: o que o CORS impede é que o JavaScript leia a resposta. Uma requisição simples chega ao servidor e é processada mesmo sem permissão de CORS. Em casos como cabeçalhos personalizados, o navegador primeiro consulta o servidor com uma requisição OPTIONS (preflight) e não envia a requisição real se ela não for permitida.

Como ele se diferencia de mecanismos parecidos

O CORS é frequentemente confundido com mecanismos de nome parecido e com uma vulnerabilidade muito próxima.

TermoO que decideQuem aplica
Política de mesma origemOutras origens não podem ler respostas (padrão do navegador)O navegador
CORSComo exceção a isso, quais origens podem lerO servidor declara, o navegador aplica
CSRFUm ataque que faz o navegador logado do usuário enviar requisições não desejadasEvitado com tokens CSRF e SameSite
CSPQuais scripts e conexões a sua própria página pode carregarO servidor declara, o navegador aplica

O CORS trata de "a resposta pode ser lida?"; o CSRF trata de "uma requisição pode ser enviada em nome do usuário?". Endurecer o CORS não evita CSRF.

O que torna uma configuração perigosa

Configurações perigosas (comuns)

  • Refletir a Origin da requisição de volta como permitida
  • Access-Control-Allow-Origin: * mais permitir credenciais
  • Abrir APIs amplamente para origem cruzada que não precisam disso

Configurações seguras

  • Uma lista de permissões (apenas origens fixas e confiáveis)
  • Negar por padrão para todo o resto
  • Para requisições com credenciais, uma origem específica, não *
O JS do site de um atacante requisita sua API (o usuário está logado)
↓ o servidor permite cegamente a Origin (configuração incorreta)
o navegador permite ler a resposta = dados pessoais/tokens chegam ao site do atacante
Com uma configuração frouxa, o JS do site de um atacante pode usar o estado logado do usuário para ler a resposta da API.

Como as configurações incorretas costumam surgir

A maioria das configurações incorretas nasce da tentativa de fazer um erro de CORS sumir. A sequência típica:

  1. Chamar a API a partir do front-end com cookies gera um erro de CORS
  2. Você adiciona Access-Control-Allow-Origin: *. Mas, em requisições com credenciais, o navegador não deixa a página ler uma resposta com *, então o erro continua
  3. Você passa a devolver a Origin que chegou, e o erro desaparece. Ao mesmo tempo, qualquer site agora pode ler respostas de usuários logados

Mesmo com uma lista de permissões, uma comparação descuidada leva ao mesmo lugar.

  • Comparar "termina com example.com" também deixa passar outro domínio, como evil-example.com
  • Comparar "começa com https://example.com" também deixa passar https://example.com.evil.net
  • Permitir a origem null por conveniência no desenvolvimento também permite leituras a partir de origens null que outros sites conseguem produzir

Compare a origem inteira (esquema, host e porta) buscando correspondência exata.

Os fundamentos de uma configuração segura

1

Use uma lista de permissões (o mais importante)

Permita apenas origens confiáveis previamente decididas e negue o resto (negar por padrão). Não "simplesmente permita tudo".
2

Não reflita a Origin cegamente

Não ecoe a Origin da requisição diretamente em Access-Control-Allow-Origin. Retorne-a apenas quando ela corresponder à lista de permissões. Como o valor passa a variar por requisição, envie também Vary: Origin para que os caches não misturem respostas.
3

Nunca use * com credenciais

Não combine Access-Control-Allow-Origin: * com Allow-Credentials: true. Nomeie uma origem específica em vez disso.
4

Minimize o que você abre

Apenas os endpoints que genuinamente precisam ser de origem cruzada. Não abra amplamente. Use * apenas para dados públicos que não exigem login.

Como verificar o seu próprio site

Envie à sua API uma requisição que declare outra origem e observe os cabeçalhos de resposta. Faça isso apenas contra APIs que você administra.

# Declare uma origem que você não permitiu e veja apenas os cabeçalhos de resposta
curl -s -o /dev/null -D - -H "Origin: https://example.com" https://your-api.example/ | grep -i "^access-control"
  • Se voltar Access-Control-Allow-Origin: https://example.com, a API está refletindo a Origin. Adicione a comparação com a lista de permissões
  • Se aparecerem juntos Access-Control-Allow-Origin: * e Access-Control-Allow-Credentials: true, revise a configuração
  • Se nada voltar, ou voltar apenas a origem do seu próprio front-end, está tudo certo

Repita a mesma verificação com Origin: null. Para um site cuja propriedade você verificou, a auditoria de segurança do site checa a reflexão da origem e as configurações de credenciais em conjunto. Os demais cabeçalhos de segurança podem ser verificados com o verificador de cabeçalhos de segurança.

A visão deste site: o CORS é 'como você afrouxa', não 'defesa' — estreite a quem você abre

Uma crença equivocada comum é "adicionar cabeçalhos CORS torna seguro". É o contrário: o CORS afrouxa a restrição do navegador. Então o que importa não é "como você adiciona", mas "minimizar a quem, e até onde, você abre."

Neste site separamos dados que podem ser lidos externamente dos que não podem, e recomendamos negar por padrão, com uma lista de permissões abrindo apenas as exceções. Note que XSS (que quebra a premissa de leitura) e CSRF (que tem como alvo mudanças de estado) são bugs separados — o CORS sozinho não cobre tudo.

Fontes (primárias)

  • MDN Web Docs, "Cross-Origin Resource Sharing (CORS)" (em inglês) — developer.mozilla.org (sem * em requisições com credenciais, condições do preflight, Vary: Origin)
  • WHATWG Fetch Standard, "CORS protocol" (em inglês) — fetch.spec.whatwg.org
  • OWASP HTML5 Security Cheat Sheet (em inglês) — cheatsheetseries.owasp.org (permitir apenas domínios confiáveis; não devolver o cabeçalho Origin sem checagem)
  • PortSwigger Web Security Academy, "Cross-origin resource sharing (CORS)" (em inglês) — portswigger.net (erros na comparação com a lista de permissões, a origem null, CORS não é proteção contra CSRF)
  • MITRE CWE-942: Permissive Cross-domain Policy with Untrusted Domains (em inglês) — cwe.mitre.org

Leia a seguir

Classificação

O CWE classifica os tipos de fraqueza por trás das vulnerabilidades; o MITRE ATT&CK classifica as técnicas dos atacantes. Ambos são mantidos pela MITRE e amplamente usados para rotular vulnerabilidades e regras de detecção.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QPara que serve o CORS?
A

Os navegadores aplicam uma política de mesma origem: o JavaScript de uma origem (site) não pode ler livremente as respostas de outro site. O CORS (Cross-Origin Resource Sharing) é como um servidor abre essa exceção — mas apenas para as partes que ele permite explicitamente. Cabeçalhos de resposta como Access-Control-Allow-Origin declaram quais origens podem ler a resposta.

QO que uma configuração incorreta de CORS expõe?
A

Permissões frouxas demais podem deixar o site de um atacante ler, via JavaScript, as respostas de API de um usuário logado. Casos clássicos: refletir de volta como permitida a Origin da requisição, ou definir Access-Control-Allow-Origin como * enquanto também permite credenciais (cookies). O resultado é que dados pessoais ou tokens podem chegar a um site de terceiros.

QQual é a base de uma configuração segura?
A

Uma lista de permissões. Permita apenas origens confiáveis previamente decididas e negue o resto (negar por padrão). Não reflita cegamente a Origin da requisição. Para requisições com credenciais, não use * em Access-Control-Allow-Origin — nomeie uma origem específica. E exponha apenas os endpoints que genuinamente precisam ser de origem cruzada.

QEstou recebendo um erro de CORS — devo definir Access-Control-Allow-Origin como *?
A

Para uma API que só devolve dados públicos, sem login, * não tem problema. Mas, em requisições que levam credenciais como cookies, o navegador não deixa a página ler uma resposta com *, então o erro continua. Se você passar a devolver qualquer Origin que chegar, qualquer site poderá ler a resposta. A correção certa é colocar a origem do seu próprio front-end numa lista de permissões e devolvê-la apenas quando houver correspondência exata.

QConfigurar o CORS evita CSRF?
A

Não. O CORS controla se uma resposta pode ser lida, não se uma requisição é enviada. Requisições simples (como um POST no formato de envio de formulário) chegam ao servidor mesmo sem permissão de CORS. Evite CSRF com tokens CSRF e o atributo SameSite dos cookies.

QO que é uma requisição de preflight?
A

Antes de enviar a requisição real, o navegador pergunta ao servidor, com uma requisição OPTIONS, se aquele método e aqueles cabeçalhos são permitidos. Isso acontece com cabeçalhos personalizados, POST com application/json, PUT, DELETE e similares. Se não for permitido, a requisição real não é enviada. Requisições simples — GET, HEAD ou POST usando apenas os cabeçalhos e tipos de conteúdo permitidos — não disparam preflight.