CORS Finalmente Explicado — De Forma Simples
Já viu isso antes? Provavelmente… e provavelmente várias vezes…
Existem milhões de artigos explicando como corrigir o erro acima, mas o que exatamente é essa coisa chamada “Cross-Origin Resource Sharing” (CORS) e por que ela existe?
Por quê???
Vamos começar respondendo à pergunta “por quê?” com um cenário e analisando como ele se desenrolava em diferentes momentos no tempo.
Imagine o seguinte: você faz login em bank.com, que é o seu serviço bancário. Após o login, um “cookie de sessão” é armazenado no seu navegador. (Cookies de sessão basicamente informam ao servidor por trás de bank.com que seu navegador está agora conectado à sua conta). Todas as solicitações futuras para bank.com agora conterão este cookie, permitindo que o servidor responda corretamente sabendo que você está conectado.
Ok, agora você decide verificar sua caixa de entrada de e-mails. Você vê um e-mail suspeito e, claro, decide clicar no link que o leva para attack.com. Esse site, então, envia uma solicitação para bank.com para obter seus dados bancários. Lembre-se de que bank.com ainda pensa que você está conectado por causa daquele cookie de sessão… Esse cookie está armazenado no seu navegador. Para os servidores por trás de bank.com, parece que você solicitou seus dados bancários normalmente, então eles os enviam de volta. Agora, attack.com tem acesso a essas informações e as armazena de forma maliciosa em outro lugar.
As pessoas perceberam que isso era um problema, então os navegadores adotaram a Same-Origin Policy (SOP). Essa política impede que o navegador envie solicitações para bank.com a partir de qualquer lugar que não seja bank.com.
Agora, aqui está algo importante a ser entendido: essa é uma política baseada no navegador. bank.com realmente não tem como saber de onde vem uma solicitação, então ele não pode se proteger muito contra ataques como CSRF. O navegador intervém e basicamente diz que, se parecer que você está tentando solicitar detalhes de uma origem (esquema + nome de domínio + porta, como https://foo.com:4000 ou http://bar.org:3000), ele só enviará essas solicitações para a mesma origem.
Isso foi ótimo, mas extremamente limitante. As APIs públicas, por exemplo, não funcionam de jeito nenhum. Você não poderia solicitar dados delas, a menos que usasse algum tipo de solução de proxy.
CSRF
Aqui está o ponto: os servidores podem, de certa forma, saber de onde vem uma solicitação. Existe o cabeçalho “Origin”, que as solicitações devem incluir, indicando qual origem fez a solicitação. Por exemplo, no caso acima, a solicitação seria algo como:
Solicitação para —–> bank.com
json
{ “Headers”: { “Origin”: “http://attack.com” }
Teoricamente, bank.com deveria verificar isso para garantir que responde apenas a solicitações de origens confiáveis. E geralmente faz, então a SOP parece meio limitante.
É aqui que entra o CORS.
CORS
Quando um aplicativo web de example.com tenta solicitar recursos de bank.com, o navegador automaticamente inclui um cabeçalho Origin na solicitação, indicando de onde ela se origina (example.com). Eis a parte crucial: em vez de simplesmente bloquear tais solicitações de origem cruzada devido à SOP, o servidor de bank.com pode inspecionar esse cabeçalho Origin e decidir permitir ou negar a solicitação com base em sua própria política de CORS.
Se bank.com considerar example.com confiável ou os recursos solicitados forem destinados ao acesso público, ele pode responder com cabeçalhos específicos de CORS, como Access-Control-Allow-Origin, indicando quais origens têm permissão para acessar o recurso. Esse cabeçalho pode ser configurado como http://example.com, permitindo explicitamente essa origem, ou como * para recursos públicos acessíveis por qualquer origem.
Claro, o navegador gerencia tudo isso. Se algo estiver errado, você verá aquele erro irritante.
E se a solicitação não tiver o cabeçalho Origin?
Ou se ela incluir vários outros cabeçalhos e não usar um dos métodos HTTP básicos?
Nesses casos, o manuseio do CORS se torna um pouco mais complexo, e é aí que entra o conceito de “pré-verificação” (preflight).
Pré-verificação (Preflight)
Para certos tipos de solicitações que podem potencialmente modificar dados no servidor — aquelas que usam métodos HTTP como PUT ou DELETE, ou incluem cabeçalhos personalizados — os navegadores enviam primeiro uma solicitação de pré-verificação antes de fazer a solicitação real.
Essa solicitação de pré-verificação é uma solicitação HTTP OPTIONS cujo objetivo é verificar com o servidor se a solicitação real é segura para ser enviada.
O processo é o seguinte:
- Solicitação do navegador: O navegador envia uma solicitação de pré-verificação ao servidor, incluindo cabeçalhos que descrevem o método HTTP e os cabeçalhos da solicitação real.
- Resposta do servidor: Se o servidor suporta a política de CORS e a solicitação real, ele responde com cabeçalhos indicando os métodos e cabeçalhos permitidos, como Access-Control-Allow-Methods e Access-Control-Allow-Headers.
- Decisão do navegador: Com base na resposta do servidor, o navegador decide se deve prosseguir com a solicitação real. Se a resposta indicar que a solicitação é permitida, o navegador a enviará ; caso contrário, ele bloqueia a solicitação, e você verá um erro relacionado ao CORS.
Conclusão
Agora, espero que você entenda um pouco mais sobre o CORS. O mais importante a perceber é que tudo isso é uma política do navegador, e seu servidor precisa ser codificado para estar em conformidade com ela. O CORS existe para mantê-lo seguro.
Se você estiver usando um navegador como o Chrome, não precisa se preocupar tanto em clicar em links maliciosos (embora ainda deva ter cuidado!). Contudo, essa política não é infalível. Se você usar um navegador de terceiros que não cumpra os padrões, todo esse esforço será inútil. Por isso, é importante sempre ter cuidado com o software que você utiliza!