Quais são os riscos de segurança da configuração do Access-Control-Allow-Origin?

124

Recentemente, tive que definir Access-Control-Allow-Originpara *poder fazer chamadas ajax entre subdomínios.
Agora não posso deixar de sentir que estou colocando meu ambiente em risco à segurança.
Por favor me ajude se eu estiver fazendo errado.

Hamed Momeni
fonte

Respostas:

69

Ao responder Access-Control-Allow-Origin: *, o recurso solicitado permite o compartilhamento com todas as origens. Isso basicamente significa que qualquer site pode enviar uma solicitação XHR ao seu site e acessar a resposta do servidor, o que não seria o caso se você não tivesse implementado essa resposta do CORS.

Portanto, qualquer site pode fazer uma solicitação ao seu site em nome de seus visitantes e processar sua resposta. Se você implementou algo como um esquema de autenticação ou autorização baseado em algo fornecido automaticamente pelo navegador (cookies, sessões baseadas em cookies etc.), as solicitações acionadas pelos sites de terceiros também os usarão.

Isso realmente representa um risco à segurança, principalmente se você permitir o compartilhamento de recursos, não apenas para os recursos selecionados, mas para todos os recursos. Nesse contexto, você deve dar uma olhada em Quando é seguro ativar o CORS? .

quiabo
fonte
2
Se você puder dar um exemplo específico de como o acesso de autenticação compartilhado representa um risco à segurança, eu votarei nisso.
quer
1
@Gumbo E o conteúdo estático? (por exemplo, conteúdo estático do CDN, como javascripts, css, htmls estáticos etc.) Há algum problema de segurança Access-Control-Allow-Origin: *na configuração deles? Não haverá nada etc, eles são públicos a todos?
Umut Benzer
2
@UmutBenzer Está tudo bem.
Gumbo #
25
Na verdade, essa resposta não está correta de acordo com o padrão CORS atual : "A cadeia '*' não pode ser usada para um recurso que suporta credenciais." Portanto, você não pode forçar uma solicitação a usar autenticação transitória na forma de cookies, autenticação HTTP em cache ou certificados SSL do cliente. No entanto, se, por exemplo, o site usasse armazenamento local para autenticação, isso seria um problema.
Niklas B.
2
@ NiklasB: Tentei esse cenário e o Chrome segue o padrão CORS, como você mencionou. isto é, a string " " não é suportada com uma solicitação de credenciais. Aqui está o que é relatado pelo Chrome: "XMLHttpRequest não pode carregar localhost: 12346 / hello . Um curinga ' ' não pode ser usado no cabeçalho 'Access-Control-Allow-Origin' quando o sinalizador de credenciais for verdadeiro. Origin ' localhost: 12345 ' portanto, não é permitido o acesso. O modo de credenciais de um XMLHttpRequest é controlado pelo atributo withCredentials. "
encarregado
37

Access-Control-Allow-Origin: *é totalmente seguro adicionar a qualquer recurso, a menos que esse recurso contenha dados particulares protegidos por algo diferente de credenciais padrão (cookies, autenticação básica, certificados de cliente TLS).

Por exemplo: Dados protegidos por cookies são seguros

Imagine https://example.com/users-private-data, o que pode expor dados particulares, dependendo do estado de logon do usuário. Este estado usa um cookie de sessão. É seguro adicionar Access-Control-Allow-Origin: *a esse recurso, pois esse cabeçalho só permite acesso à resposta se a solicitação for feita sem cookies e forem necessários cookies para obter os dados privados. Como resultado, nenhum dado privado vazou.

Por exemplo: Dados protegidos por localização / ip / rede interna não são seguros (infelizmente são comuns em intranets e eletrodomésticos):

Imagine https://intranet.example.com/company-private-data, que expõe dados de empresas privadas, mas isso só pode ser acessado se você estiver na rede wifi da empresa. Não é seguro adicionar Access-Control-Allow-Origin: *a esse recurso, pois ele é protegido usando algo diferente de credenciais padrão. Caso contrário, um script incorreto pode usar você como um túnel para a intranet.

Regra prática

Imagine o que um usuário veria se acessasse o recurso em uma janela anônima. Se você está satisfeito com todos que veem esse conteúdo (incluindo o código-fonte que o navegador recebeu), é seguro adicionar Access-Control-Allow-Origin: *.

JaffaTheCake
fonte
deve "como permite apenas solicitações sem cookies" ser "como permite apenas solicitações com cookies"?
DJCordhose
3
@DJCordhose no. Access-Control-Allow-Origin: *só permite solicitações sem cookies. Eu editei a resposta para esclarecer um pouco.
JaffaTheCake 5/19
Qual é a diferença entre "*" e case sem esse cabeçalho? É o mesmo?
Nigrimmist
Eu adoraria se "Caso contrário, um script ruim poderia usá-lo como um túnel para a intranet" poderia ser mais explicado.
Sam Rueby 9/10/19
@Nigrimmist Então a solicitação de comprovação falhará e o acesso aos recursos será bloqueado
iamareebjamal 28/01
9

AFAIK, Access-Control-Allow-Origin é apenas um cabeçalho http enviado do servidor para o navegador. Limitá-lo a um endereço específico (ou desativá-lo) não torna seu site mais seguro, por exemplo, para robôs. Se os robôs quiserem, eles podem simplesmente ignorar o cabeçalho. Por padrão, os navegadores comuns (Explorer, Chrome etc.) respeitam o cabeçalho. Mas um aplicativo como o Postman simplesmente o ignora.

O final do servidor não verifica realmente qual é a 'origem' da solicitação quando retorna a resposta. Apenas adiciona o cabeçalho http. É o navegador (o cliente final) que enviou a solicitação que decide ler o cabeçalho de controle de acesso e agir de acordo com ele. Observe que, no caso do XHR, ele pode usar uma solicitação especial de 'OPÇÕES' para solicitar primeiro os cabeçalhos.

Portanto, qualquer pessoa com capacidade criativa de script pode ignorar facilmente todo o cabeçalho, o que for definido nele.

Consulte também Possíveis problemas de segurança da configuração do Access-Control-Allow-Origin .


Agora, para realmente responder à pergunta

Não posso deixar de sentir que estou colocando meu ambiente em risco à segurança.

Se alguém quiser atacá-lo, poderá ignorar facilmente o Access-Control-Allow-Origin. Porém, ao habilitar '*', você fornece ao atacante mais alguns 'vetores de ataque' para brincar, como usar navegadores da Web comuns que respeitam esse cabeçalho HTTP.

commonpike
fonte
6
Veja isso do ponto de vista de um usuário final incauto. Alguém pode configurar uma página da Web maliciosa que injeta JavaScript para transmitir dados entre o site real e um site malicioso (digamos que eles desejam roubar sua senha). O navegador da web do usuário final normalmente bloqueia essa comunicação entre sites, mas se o Acesso-Controle-Permitir-Origem estiver definido, será permitido e o usuário final não será o mais sábio.
precisa saber é o seguinte
3
Sim, a configuração Access-Control-Allow-Origin *em um site mal-intencionado que hospeda scripts para roubar senhas é altamente desencorajada :-)
commonpike
6
Você está certo, pois alguém poderia criar um script para ignorar totalmente o cabeçalho. Se os dados estiverem acessíveis, poderão ser acessados ​​com ou sem cabeçalhos CORS. Há outro vetor de ataque que você não está considerando. Suponha que eu entre no site do meu banco. Se eu for para outra página e depois voltar para o meu banco, ainda estou logado por causa de um cookie. Outros usuários da Internet podem acessar os mesmos URLs no meu banco que eu, mas eles não poderão acessar minha conta sem o cookie. Se forem permitidas solicitações de origem cruzada, um site mal-intencionado pode se passar por ...
Brad
5
@commonpike ... o usuário. Dito de outra forma, você pode apenas visitar meu site (que pode até ser um site normal, sem nada de suspeito ... talvez seja um site legítimo real que tenha sido invadido!), Mas com algum JavaScript que solicite HTTP ao seu banco para transferir alguns fundos para minha conta. O banco não sabe a diferença entre solicitações de suas páginas ou solicitações de outras páginas. Ambos possuem esse cookie, permitindo que a solicitação seja bem-sucedida.
Brad
3
@commonpike Deixe-me dar um exemplo mais comum ... que acontece o tempo todo. Suponha que você tenha um roteador doméstico comum, como um Linksys WRT54g ou algo assim. Suponha que o roteador permita solicitações de origem cruzada. Um script na minha página da Web pode fazer solicitações HTTP para endereços IP comuns do roteador (como 192.168.1.1) e reconfigurar seu roteador para permitir ataques. Pode até usar seu roteador diretamente como um nó DDoS. (A maioria dos roteadores tem páginas de teste que permitem a pings ou cheques servidor HTTP simples Estes podem ser abusado em massa..)
Brad
7

Aqui estão 2 exemplos postados como comentários, quando um curinga é realmente problemático:

Suponha que eu entre no site do meu banco. Se eu for para outra página e depois voltar para o meu banco, ainda estou logado por causa de um cookie. Outros usuários da Internet podem acessar os mesmos URLs no meu banco que eu, mas eles não poderão acessar minha conta sem o cookie. Se solicitações de origem cruzada forem permitidas, um site mal-intencionado pode efetivamente representar o usuário.

- Brad

Suponha que você tenha um roteador doméstico comum, como um Linksys WRT54g ou algo assim. Suponha que o roteador permita solicitações de origem cruzada. Um script na minha página da web pode fazer solicitações HTTP para endereços IP comuns do roteador (como 192.168.1.1) e reconfigurar o roteador para permitir ataques. Pode até usar seu roteador diretamente como um nó DDoS. (A maioria dos roteadores possui páginas de teste que permitem pings ou verificações simples do servidor HTTP. Elas podem ser abusadas em massa.)

- Brad

Sinto que esses comentários deveriam ter sido respostas, porque explicam o problema com um exemplo da vida real.

Christian Gollhardt
fonte
8
Exceto que isso não vai funcionar. "A cadeia '*' não pode ser usada para um recurso que suporta credenciais." w3.org/TR/cors/#resource-requests
bayo
@bayotop Como o navegador distingue entre as páginas que exigem autenticação e aquelas com outros dados nos cabeçalhos?
Wedstrom 8/08
Depois de ler o link fornecido, há "sinalizador de credenciais de suporte" que é usado para essa finalidade. Parece ter sido definido manualmente, então, presumivelmente, se alguém não soubesse configurar corretamente o CORS, também poderia errar esse sinalizador, então acredito que as vulnerabilidades acima sejam possíveis.
Wedstrom 8/08
2
@wedstrom O sinalizador é definido por quem faz a solicitação. De qualquer forma, os cenários acima são exemplos de ataques CSRF. Permitir a origem '*' não o tornará mais vulnerável do que você já é (talvez um pouco em casos raros). Na maioria dos casos, você pode fazer a solicitação entre sites maliciosa usando formulários para que o CORS não importe. Nos casos em que você precisa fazer uma solicitação AJAX, as solicitações pré-voo serão um obstáculo (este é o ponto em que o navegador entra quando ACAO: '*' e Credenciais de permissão de controle de acesso: 'true').
bayo
0

No cenário em que o servidor tenta desativar completamente o CORS, definindo os cabeçalhos abaixo.

  • Access-Control-Allow-Origin: * (informa ao navegador que o servidor aceita solicitações entre sites de qualquer ORIGIN)

  • Access-Control-Allow-Credentials: true (informa ao navegador que solicitações entre sites podem enviar cookies)

Existe uma falha de segurança implementada nos navegadores que resultará no erro abaixo

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

Portanto, na maioria dos cenários, definir 'Acesso-controle-permissão-origem' para *não será um problema. No entanto, para proteger contra ataques, o servidor pode manter uma lista de origens permitidas e, sempre que o servidor recebe uma solicitação de origem cruzada, pode validar o cabeçalho ORIGIN na lista de origens permitidas e, em seguida, repetir o mesmo em Access-Control-Allow-Origin cabeçalho.

Como o cabeçalho ORIGIN não pode ser alterado pelo javascript em execução no navegador, o site malicioso não poderá falsificá-lo.

shadow0359
fonte